Final cleanup of Persist Module. Pending a sanity check of the dynamic finder API, it is now ready to ship for Guice 3!

git-svn-id: https://google-guice.googlecode.com/svn/trunk@1227 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/extensions/persist/src/com/google/inject/persist/PersistFilter.java b/extensions/persist/src/com/google/inject/persist/PersistFilter.java
new file mode 100644
index 0000000..2fc7a5f
--- /dev/null
+++ b/extensions/persist/src/com/google/inject/persist/PersistFilter.java
@@ -0,0 +1,94 @@
+/**

+ * Copyright (C) 2010 Google, Inc.

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package com.google.inject.persist;

+

+import com.google.inject.Inject;

+import com.google.inject.Singleton;

+import java.io.IOException;

+import javax.servlet.Filter;

+import javax.servlet.FilterChain;

+import javax.servlet.FilterConfig;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse;

+

+/**

+ * Apply this filter to enable the HTTP Request unit of work and to have

+ * guice-persist manage the lifecycle of active units of work.

+ * The filter automatically starts and stops the relevant {@link PersistService}

+ * upon {@link javax.servlet.Filter#init(javax.servlet.FilterConfig)} and

+ * {@link javax.servlet.Filter#destroy()} respectively.

+ *

+ * <p> To be able to use the open session-in-view pattern (i.e. work per request),

+ * register this filter <b>once</b> in your Guice {@code ServletModule}. It is

+ * important that you register this filter before any other filter.

+ *

+ * For multiple providers, you should register this filter once per provider, inside

+ * a private module for each persist module installed (this must be the same private

+ * module where the specific persist module is itself installed).

+ *

+ * <p>

+ * Example configuration:

+ * <pre>{@code

+ *  public class MyModule extends ServletModule {

+ *    public void configureServlets() {

+ *      filter("/*").through(PersistFilter.class);

+ *

+ *      serve("/index.html").with(MyHtmlServlet.class);

+ *      // Etc.

+ *    }

+ *  }

+ * }</pre>

+ * <p>

+ * This filter is thread safe and allows you to create injectors concurrently

+ * and deploy multiple guice-persist modules within the same injector, or even

+ * multiple injectors with persist modules withing the same JVM or web app.

+ * <p>

+ * This filter requires the Guice Servlet extension.

+ *

+ * @author Dhanji R. Prasanna (dhanji@gmail.com)

+ */

+@Singleton

+public final class PersistFilter implements Filter {

+  private final UnitOfWork unitOfWork;

+  private final PersistService persistService;

+

+  @Inject

+  public PersistFilter(UnitOfWork unitOfWork, PersistService persistService) {

+    this.unitOfWork = unitOfWork;

+    this.persistService = persistService;

+  }

+

+  public void init(FilterConfig filterConfig) throws ServletException {

+    persistService.start();

+  }

+

+  public void destroy() {

+    persistService.stop();

+  }

+

+  public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,

+      final FilterChain filterChain) throws IOException, ServletException {

+

+    unitOfWork.begin();

+    try {

+      filterChain.doFilter(servletRequest, servletResponse);

+    } finally {

+      unitOfWork.end();

+    }

+  }

+}

diff --git a/extensions/persist/src/com/google/inject/persist/PersistModule.java b/extensions/persist/src/com/google/inject/persist/PersistModule.java
index ddbad19..6703cb5 100644
--- a/extensions/persist/src/com/google/inject/persist/PersistModule.java
+++ b/extensions/persist/src/com/google/inject/persist/PersistModule.java
@@ -1,70 +1,44 @@
+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.persist;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.BindingAnnotation;
-import com.google.inject.internal.util.Preconditions;
 import static com.google.inject.matcher.Matchers.annotatedWith;
 import static com.google.inject.matcher.Matchers.any;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import org.aopalliance.intercept.MethodInterceptor;
 
 /**
  * Install this module to add guice-persist library support for JPA persistence
  * providers.
  *
- * @author dhanji@google.com (Dhanji R. Prasanna)
+ * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public abstract class PersistModule extends AbstractModule {
-  private Class<? extends Annotation> unitOfWork;
-  private Class<? extends Annotation> transactional;
 
   @Override
   protected final void configure() {
     configurePersistence();
 
-    if (null == unitOfWork) {
-      // We bind this as the "Default" work manager if no custom unit of work is used.
-      bind(WorkManager.class).to(getWorkManager());
-      unitOfWork = UnitOfWork.class;
-    }
-    if (null == transactional) {
-      transactional = Transactional.class;
-    }
-
-    // NOTE(dhanji): Bind work-specific work manager + transaction interceptors.
-    // We permit the default work manager to be bound to both the default work
-    // annotation @UnitOfWork, and without any annotation. Default is defined as
-    // any persistence module without a custom unit of work annotation. In a single
-    // module system, the single module would be the default (most typical apps).
-    bind(WorkManager.class).annotatedWith(unitOfWork).to(getWorkManager());
-    bindInterceptor(any(), annotatedWith(transactional), getTransactionInterceptor());
+    requireBinding(PersistService.class);
+    requireBinding(UnitOfWork.class);
+    bindInterceptor(any(), annotatedWith(Transactional.class), getTransactionInterceptor());
   }
 
   protected abstract void configurePersistence();
 
-  protected abstract Class<? extends WorkManager> getWorkManager();
-
   protected abstract MethodInterceptor getTransactionInterceptor();
-
-  protected final void setUnitOfWork(Class<? extends Annotation> unitOfWork) {
-    Preconditions.checkArgument(null != unitOfWork,
-        "Must specify a non-null unit of work.");
-    this.unitOfWork = unitOfWork;
-  }
-
-  protected final void setTransactional(Class<? extends Annotation> transactional) {
-    Preconditions.checkArgument(null != unitOfWork,
-        "Must specify a non-null transactional annotation.");
-    this.transactional = transactional;
-  }
-
-  /**
-   * @author dhanji@google.com (Dhanji R. Prasanna)
-   */
-  @Retention(RetentionPolicy.RUNTIME)
-  @BindingAnnotation
-  public static @interface Persist {
-  }
 }
diff --git a/extensions/persist/src/com/google/inject/persist/PersistService.java b/extensions/persist/src/com/google/inject/persist/PersistService.java
new file mode 100644
index 0000000..85d4b35
--- /dev/null
+++ b/extensions/persist/src/com/google/inject/persist/PersistService.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.inject.persist;
+
+/**
+ * Persistence provider service. Use this to manage the overall
+ * startup and stop of the persistence module(s).
+ *
+ * TODO(dhanji): Integrate with Service API when appropriate.
+ *
+ * @author dhanji@gmail.com (Dhanji R. Prasanna)
+ */
+public interface PersistService {
+
+  /**
+   * Starts the underlying persistence engine and makes guice-persist ready for
+   * use. For instance, with JPA, it creates an EntityManagerFactory and may
+   * open connection pools. This method must be called by your code prior to
+   * using any guice-persist or JPA artifacts. If already started,
+   * calling this method does nothing, if already stopped, it also does
+   * nothing.
+   */
+  void start();
+
+  /**
+   * Stops the underlying persistence engine. For instance, with JPA, it
+   * closes the {@code EntityManagerFactory}. If already stopped, calling this
+   * method does nothing. If not yet started, it also does nothing.
+   */
+  void stop();
+}
diff --git a/extensions/persist/src/com/google/inject/persist/PersistenceFilter.java b/extensions/persist/src/com/google/inject/persist/PersistenceFilter.java
deleted file mode 100644
index d427c05..0000000
--- a/extensions/persist/src/com/google/inject/persist/PersistenceFilter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**

- * Copyright (C) 2010 Google, Inc.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- * http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package com.google.inject.persist;

-

-import com.google.inject.Inject;

-import com.google.inject.Singleton;

-import java.io.IOException;

-import javax.servlet.Filter;

-import javax.servlet.FilterChain;

-import javax.servlet.FilterConfig;

-import javax.servlet.ServletException;

-import javax.servlet.ServletRequest;

-import javax.servlet.ServletResponse;

-

-/**

- * Apply this filter to enable the HTTP Request unit of work and to have

- * guice-persist manage the lifecycle of all active (module-installed)

- * {@link WorkManager} instances. The filter automatically starts and

- * stops all registered {@link WorkManager} instances upon {@link

- * javax.servlet.Filter#init(javax.servlet.FilterConfig)} and {@link

- * javax.servlet.Filter#destroy()}.

- *

- * <p> To be able to use the open session-in-view pattern (i.e. work per request),

- * register this filter <b>once</b> in your Guice {@code ServletModule}. It is

- * important that you register this filter before any other filter.

- *

- * <p>

- * Example configuration:

- * <pre>{@code

- *  public class MyModule extends ServletModule {

- *    public void configureServlets() {

- *      filter("/*").through(PersistenceFilter.class);

- *

- *      serve("/index.html").with(MyHtmlServlet.class);

- *      // Etc.

- *    }

- *  }

- * }</pre>

- * <p>

- * This filter will make sure to initialize and shutdown the underlying

- * persistence engine on filter {@code init()} and {@code destroy()}

- * respectively. Note that if you have multiple modules, this filter will

- * only start the "default" module, i.e. the {@code WorkManager} that is not

- * bound to any annotation.

- * <p>

- * Even though all mutable state is package local, this filter is thread safe.

- * This allows you to create injectors concurrently and deploy multiple

- * guice-persist applications within the same JVM or servlet container.

- *

- * @author Dhanji R. Prasanna (dhanji@gmail.com)

- */

-@Singleton

-public final class PersistenceFilter implements Filter {

-  private final WorkManager workManager;

-

-  @Inject

-  public PersistenceFilter(WorkManager workManager) {

-    this.workManager = workManager;

-  }

-

-  public void init(FilterConfig filterConfig) throws ServletException {

-    workManager.startPersistence();

-  }

-

-  public void destroy() {

-    workManager.shutdownPersistence();

-  }

-

-  public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,

-      final FilterChain filterChain) throws IOException, ServletException {

-    filterChain.doFilter(servletRequest, servletResponse);

-  }

-}

diff --git a/extensions/persist/src/com/google/inject/persist/Transactional.java b/extensions/persist/src/com/google/inject/persist/Transactional.java
index 089275c..02526b4 100644
--- a/extensions/persist/src/com/google/inject/persist/Transactional.java
+++ b/extensions/persist/src/com/google/inject/persist/Transactional.java
@@ -25,16 +25,15 @@
 /**
  * <p> Any method or class marked with this annotation will be considered for transactionality.
  * Consult the documentation on http://code.google.com/p/google-guice for detailed semantics.
- * Marking a method {@code @Transactional} will work with the default configuration as expected.
- *  Any classes marked {@code @Transactional} will only work if you specify the
- *  {@code forAll(Matchers.annotatedWith(Transactional.class), Matchers.any()} clause in your
- * guice-persist module configuration.
- *
- * Class level {@code @Transactional} allows you to specify transaction semantics for all
- * non-private methods in the class once at the top. You can optionally override it on a
- * per-method basis too. However, this means that classes not marked {@code @Transactional}
- *  but with methods marked {@code @Transactional} will *not* be intercepted for transaction
- *  wrapping.
+ * Marking a method {@code @Transactional} will start a new transaction before the method
+ * executes and commit it after the method returns.
+ * <p>
+ * If the method throws an exception, the transaction will be rolled back <em>unless</em>
+ * you have specifically requested not to in the {@link #ignore()} clause.
+ * <p>
+ * Similarly, the set of exceptions that will trigger a rollback can be defined in
+ * the {@link #rollbackOn()} clause. By default, only unchecked exceptions trigger a
+ * rollback.
  *
  * @author Dhanji R. Prasanna (dhanji@gmail.com)
  */
diff --git a/extensions/persist/src/com/google/inject/persist/UnitOfWork.java b/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
old mode 100644
new mode 100755
index aacfadc..061a6ab
--- a/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
+++ b/extensions/persist/src/com/google/inject/persist/UnitOfWork.java
@@ -1,18 +1,57 @@
+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.persist;
 
-import com.google.inject.BindingAnnotation;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
- * The Default unit of work binding annotation used to bind persistence
- * artifacts to. You may also place this annotation on methods to intercept
- * and wrap them with a unit of work (i.e. start and end work around methods).
- * This is analogous to starting an ending transactions but at a coarser
- * granularity. For example, in JPA a unit of work would span a single
- * {@code EntityManager}'s lifespan. 
+ * This interface is used to gain manual control over the unit of work. This is mostly to do
+ * work in non-request, non-transactional threads. Or where more fine-grained control over the unit
+ * of work is required. Starting and ending a unit of work directly corresponds to opening and
+ * closing a {@code Session}, {@code EntityManager} or {@code ObjectContainer} respectively.
+ * <p> The
+ * Unit of Work referred to by UnitOfWork will always be local to the calling thread. Be careful to
+ * end() in a finally block. Neither JPA, nor Hibernate supports threadsafe sessions (reasoning
+ * behind thread-locality of Unit of Work semantics).
+ *
+ * <ul>
+ *   <li>Using UnitOfWork with the PersistFilter inside a request is not recommended.</li>
+ *   <li>Using UnitOfWork with session-per-txn strategy is not terribly clever either.</li>
+ *   <li>Using UnitOfWork with session-per-request strategy but *outside* a request (i.e. in a
+ *       background or bootstrap thread) is probably a good use case.</li>
+ *  </ul>
+ *
+ * @author Dhanji R. Prasanna (dhanji@gmail com)
  */
-@Retention(RetentionPolicy.RUNTIME)
-@BindingAnnotation
-public @interface UnitOfWork {
+public interface UnitOfWork {
+
+  /**
+   * Starts a Unit Of Work. Underneath, causes a session to the data layer to be opened. If there
+   * is already one open, the invocation will do nothing. In this way, you can define arbitrary
+   * units-of-work that nest within one another safely.
+   *
+   * Transaction semantics are not affected.
+   */
+  void begin();
+
+  /**
+   * Declares an end to the current Unit of Work. Underneath, causes any open session to the data
+   * layer to close. If there is no Unit of work open, then the call returns silently. You can
+   * safely invoke end() repeatedly.
+   * <p>
+   * Transaction semantics are not affected.
+   */
+  void end();
 }
diff --git a/extensions/persist/src/com/google/inject/persist/WorkManager.java b/extensions/persist/src/com/google/inject/persist/WorkManager.java
deleted file mode 100755
index 32cfe71..0000000
--- a/extensions/persist/src/com/google/inject/persist/WorkManager.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (C) 2010 Google, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.inject.persist;
-
-/**
- * This interface is used to gain manual control over the unit of work. This is mostly to do
- * work in non-request, non-transactional threads. Or where more fine-grained control over the unit
- * of work is required. Starting and ending a unit of work directly corresponds to opening and
- * closing a {@code Session}, {@code EntityManager} or {@code ObjectContainer} respectively.
- * <p> The
- * Unit of Work referred to by WorkManager will always be local to the calling thread. Be careful to
- * end() in a finally block. Neither JPA, nor Hibernate supports threadsafe sessions (reasoning
- * behind thread-locality of Unit of Work semantics).
- *
- * <ul>
- *   <li>Using WorkManager with the PersistenceFilter inside a request is not recommended.</li>
- *   <li>Using WorkManager with session-per-txn strategy is not terribly clever either.</li>
- *   <li>Using WorkManager with session-per-request strategy but *outside* a request (i.e. in a
- *       background or bootstrap thread) is probably a good use case.</li>
- *  </ul>
- *
- * @author Dhanji R. Prasanna (dhanji gmail com)
- */
-public interface WorkManager {
-
-  /**
-   * Starts the underlying persistence engine and makes guice-persist ready for
-   * use. For instance, with JPA, it creates an EntityManagerFactory and may
-   * open connection pools. This method must be called by your code prior to
-   * using any guice-persist or JPA artifacts. If already started,
-   * calling this method does nothing, if already stopped, it also does
-   * nothing.
-   */
-  void startPersistence();
-
-  /**
-   * Stops the underlying persistence engine. For instance, with JPA, it
-   * closes the {@code EntityManagerFactory}. If already stopped, calling this
-   * method does nothing. If not yet started, it also does nothing.
-   */
-  void shutdownPersistence();
-
-  /**
-   * Starts a Unit Of Work. Underneath, causes a session to the data layer to be opened. If there
-   * is already one open, the invocation will do nothing. In this way, you can define arbitrary
-   * units-of-work that nest within one another safely.
-   *
-   * Transaction semantics are not affected.
-   */
-  void begin();
-
-  /**
-   * Declares an end to the current Unit of Work. Underneath, causes any open session to the data
-   * layer to close. If there is no Unit of work open, then the call returns silently. You can
-   * safely invoke end() repeatedly.
-   * <p>
-   * Transaction semantics are not affected.
-   */
-  void end();
-}
diff --git a/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java b/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
index 8595917..a98158a 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/DynamicFinder.java
@@ -1,4 +1,18 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 package com.google.inject.persist.finder;
 
@@ -7,7 +21,7 @@
 /**
  * Utility that helps you discover metadata about dynamic finder methods.
  *
- * @author dhanji@google.com (Dhanji R. Prasanna)
+ * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public final class DynamicFinder {
 
diff --git a/extensions/persist/src/com/google/inject/persist/finder/Finder.java b/extensions/persist/src/com/google/inject/persist/finder/Finder.java
index dde9dec..cc5f58e 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/Finder.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/Finder.java
@@ -24,32 +24,28 @@
 import java.util.Collection;

 

 /**

- * <p> Marks a method stub as a dynamic finder. The method is intercepted and replaced with the

- * specified HQL or JPAQL query. Provides result auto-boxing and automatic parameter binding. </p>

+ * Marks a method stub as a dynamic finder. The method is intercepted and replaced with the

+ * specified JPAQL query. Provides result auto-boxing and automatic parameter binding.

  *

  * @author Dhanji R. Prasanna (dhanji@gmail.com)

  */

 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)

 public @interface Finder {

   /**

-   * Specify a named query's name here, typically using the {@code @NamedQuery} annotation.

-   *

-   * @return Returns the configured named query's name.

+   * Returns the configured named query's name. Specify a named query's name

+   * here. This name is typically specified in your JPA configuration.

    */

   String namedQuery() default "";

 

   /**

-   * Directly specify a query here, hql or jpaql.

-   *

-   * @return Returns the configured query string.

+   * Returns the configured query string. Directly specify a JPAQL query here.

    */

   String query() default "";

 

   /**

-   * Use this clause to specify a collection impl to autobox result lists into. The impl *must*

+   * Returns the configured autoboxing collection class.

+   * Use this clause to specify a collection impl to autobox result lists into. The impl must

    * have a default no-arg constructor and be a subclass of {@code java.util.Collection}.

-   *

-   * @return Returns the configured autoboxing collection class.

    */

   Class<? extends Collection> returnAs() default ArrayList.class;

 }
\ No newline at end of file
diff --git a/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java b/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
index 9398f35..510ef1a 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/FirstResult.java
@@ -24,7 +24,7 @@
 /**

  * Annotate any dynamic finder method's integer argument with this to pass in

  * the index of the first result in the result set you are interested in.

- * Useful for paging result sets. Complemented by {@link NumResults}.

+ * Useful for paging result sets. Complemented by {@link MaxResults}.

  *

  * @author Dhanji R. Prasanna (dhanji@gmail.com)

  */

diff --git a/extensions/persist/src/com/google/inject/persist/finder/NumResults.java b/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
similarity index 97%
rename from extensions/persist/src/com/google/inject/persist/finder/NumResults.java
rename to extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
index c577b4a..a62aa28 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/NumResults.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/MaxResults.java
@@ -30,5 +30,5 @@
  */

 @Target(ElementType.PARAMETER)

 @Retention(RetentionPolicy.RUNTIME)

-public @interface NumResults {

+public @interface MaxResults {

 }

diff --git a/extensions/persist/src/com/google/inject/persist/finder/package-info.java b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
index 2079221..514a54f 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
@@ -1,4 +1,4 @@
 /**
- * Dynamic Finder API.
+ * Dynamic Finder API for Guice Persist.
  */
 package com.google.inject.persist.finder;
\ No newline at end of file
diff --git a/extensions/persist/src/com/google/inject/persist/finder/NumResults.java b/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
similarity index 62%
copy from extensions/persist/src/com/google/inject/persist/finder/NumResults.java
copy to extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
index c577b4a..c2f6d1d 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/NumResults.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/Jpa.java
@@ -1,34 +1,29 @@
-/**

- * Copyright (C) 2010 Google, Inc.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- * http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-

-package com.google.inject.persist.finder;

-

-import java.lang.annotation.ElementType;

-import java.lang.annotation.Retention;

-import java.lang.annotation.RetentionPolicy;

-import java.lang.annotation.Target;

-

-/**

- * Annotate any dynamic finder method's integer argument with this to pass in

- * the maximum size of returned result window. Usefule for paging result sets.

- * Complement of {@link FirstResult}.

- *

- * @author Dhanji R. Prasanna (dhanji@gmail.com)

- */

-@Target(ElementType.PARAMETER)

-@Retention(RetentionPolicy.RUNTIME)

-public @interface NumResults {

-}

+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.persist.jpa;
+
+import com.google.inject.BindingAnnotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A binding annotation for internal JPA module properties.
+ *
+ * @author dhanji@gmail.com (Dhanji R. Prasanna)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@BindingAnnotation @interface Jpa {}
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
index 2f883ba..614bff9 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaFinderProxy.java
@@ -20,7 +20,7 @@
 import com.google.inject.name.Named;

 import com.google.inject.persist.finder.Finder;

 import com.google.inject.persist.finder.FirstResult;

-import com.google.inject.persist.finder.NumResults;

+import com.google.inject.persist.finder.MaxResults;

 import java.lang.annotation.Annotation;

 import java.lang.reflect.Constructor;

 import java.lang.reflect.InvocationTargetException;

@@ -39,12 +39,12 @@
  *

  * @author Dhanji R. Prasanna (dhanji@gmail.com)

  */

-class JpaFinderInterceptor implements MethodInterceptor {

+class JpaFinderProxy implements MethodInterceptor {

   private final Map<Method, FinderDescriptor> finderCache

       = new ConcurrentHashMap<Method, FinderDescriptor>();

   private final Provider<EntityManager> emProvider;

 

-  public JpaFinderInterceptor(Provider<EntityManager> emProvider) {

+  public JpaFinderProxy(Provider<EntityManager> emProvider) {

     this.emProvider = emProvider;

   }

 

@@ -52,7 +52,7 @@
     EntityManager em = emProvider.get();

 

     //obtain a cached finder descriptor (or create a new one)

-    JpaFinderInterceptor.FinderDescriptor finderDescriptor = getFinderDescriptor(methodInvocation);

+    JpaFinderProxy.FinderDescriptor finderDescriptor = getFinderDescriptor(methodInvocation);

 

     Object result = null;

 

@@ -65,18 +65,18 @@
     }

 

     //depending upon return type, decorate or return the result as is

-    if (JpaFinderInterceptor.ReturnType.PLAIN.equals(finderDescriptor.returnType)) {

+    if (JpaFinderProxy.ReturnType.PLAIN.equals(finderDescriptor.returnType)) {

       result = jpaQuery.getSingleResult();

-    } else if (JpaFinderInterceptor.ReturnType.COLLECTION.equals(finderDescriptor.returnType)) {

+    } else if (JpaFinderProxy.ReturnType.COLLECTION.equals(finderDescriptor.returnType)) {

       result = getAsCollection(finderDescriptor, jpaQuery.getResultList());

-    } else if (JpaFinderInterceptor.ReturnType.ARRAY.equals(finderDescriptor.returnType)) {

+    } else if (JpaFinderProxy.ReturnType.ARRAY.equals(finderDescriptor.returnType)) {

       result = jpaQuery.getResultList().toArray();

     }

 

     return result;

   }

 

-  private Object getAsCollection(JpaFinderInterceptor.FinderDescriptor finderDescriptor,

+  private Object getAsCollection(JpaFinderProxy.FinderDescriptor finderDescriptor,

       List results) {

     Collection<?> collection;

     try {

@@ -100,7 +100,7 @@
   }

 

   private void bindQueryNamedParameters(Query hibernateQuery,

-      JpaFinderInterceptor.FinderDescriptor descriptor, Object[] arguments) {

+      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {

     for (int i = 0; i < arguments.length; i++) {

       Object argument = arguments[i];

       Object annotation = descriptor.parameterAnnotations[i];

@@ -114,14 +114,14 @@
         hibernateQuery.setParameter(named.value(), argument);

       } else if (annotation instanceof FirstResult) {

         hibernateQuery.setFirstResult((Integer) argument);

-      } else if (annotation instanceof NumResults) {

+      } else if (annotation instanceof MaxResults) {

         hibernateQuery.setMaxResults((Integer) argument);

       }

     }

   }

 

   private void bindQueryRawParameters(Query jpaQuery,

-      JpaFinderInterceptor.FinderDescriptor descriptor, Object[] arguments) {

+      JpaFinderProxy.FinderDescriptor descriptor, Object[] arguments) {

     for (int i = 0, index = 1; i < arguments.length; i++) {

       Object argument = arguments[i];

       Object annotation = descriptor.parameterAnnotations[i];

@@ -132,21 +132,21 @@
         index++;

       } else if (annotation instanceof FirstResult) {

         jpaQuery.setFirstResult((Integer) argument);

-      } else if (annotation instanceof NumResults) {

+      } else if (annotation instanceof MaxResults) {

         jpaQuery.setMaxResults((Integer) argument);

       }

     }

   }

 

-  private JpaFinderInterceptor.FinderDescriptor getFinderDescriptor(MethodInvocation invocation) {

+  private JpaFinderProxy.FinderDescriptor getFinderDescriptor(MethodInvocation invocation) {

     Method method = invocation.getMethod();

-    JpaFinderInterceptor.FinderDescriptor finderDescriptor = finderCache.get(method);

+    JpaFinderProxy.FinderDescriptor finderDescriptor = finderCache.get(method);

     if (null != finderDescriptor) {

       return finderDescriptor;

     }

 

     //otherwise reflect and cache finder info...

-    finderDescriptor = new JpaFinderInterceptor.FinderDescriptor();

+    finderDescriptor = new JpaFinderProxy.FinderDescriptor();

 

     //determine return type

     finderDescriptor.returnClass = invocation.getMethod().getReturnType();

@@ -177,7 +177,7 @@
         } else if (FirstResult.class.equals(annotationType)) {

           discoveredAnnotations[i] = annotation;

           break;

-        } else if (NumResults.class.equals(annotationType)) {

+        } else if (MaxResults.class.equals(annotationType)) {

           discoveredAnnotations[i] = annotation;

           break;

         }   //leave as null for no binding

@@ -188,7 +188,7 @@
     finderDescriptor.parameterAnnotations = discoveredAnnotations;

 

     //discover the returned collection implementation if this finder returns a collection

-    if (JpaFinderInterceptor.ReturnType.COLLECTION.equals(finderDescriptor.returnType)) {

+    if (JpaFinderProxy.ReturnType.COLLECTION.equals(finderDescriptor.returnType)) {

       finderDescriptor.returnCollectionType = finder.returnAs();

       try {

         finderDescriptor.returnCollectionTypeConstructor = finderDescriptor.returnCollectionType

@@ -218,14 +218,14 @@
     finderCache.put(method, finderDescriptor);

   }

 

-  private JpaFinderInterceptor.ReturnType determineReturnType(Class<?> returnClass) {

+  private JpaFinderProxy.ReturnType determineReturnType(Class<?> returnClass) {

     if (Collection.class.isAssignableFrom(returnClass)) {

-      return JpaFinderInterceptor.ReturnType.COLLECTION;

+      return JpaFinderProxy.ReturnType.COLLECTION;

     } else if (returnClass.isArray()) {

-      return JpaFinderInterceptor.ReturnType.ARRAY;

+      return JpaFinderProxy.ReturnType.ARRAY;

     }

 

-    return JpaFinderInterceptor.ReturnType.PLAIN;

+    return JpaFinderProxy.ReturnType.PLAIN;

   }

 

   /**

@@ -235,12 +235,12 @@
     private volatile boolean isKeyedQuery = false;

     volatile boolean isBindAsRawParameters = true;

         //should we treat the query as having ? instead of :named params

-    volatile JpaFinderInterceptor.ReturnType returnType;

+    volatile JpaFinderProxy.ReturnType returnType;

     volatile Class<?> returnClass;

     volatile Class<? extends Collection> returnCollectionType;

     volatile Constructor returnCollectionTypeConstructor;

     volatile Object[] parameterAnnotations;

-        //contract is: null = no bind, @Named = param, @FirstResult/@NumResults for paging

+        //contract is: null = no bind, @Named = param, @FirstResult/@MaxResults for paging

 

     private String query;

     private String name;

diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
index 2ec3de5..93d5b64 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
@@ -18,7 +18,7 @@
 

 import com.google.inject.Inject;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import java.lang.reflect.Method;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityTransaction;

@@ -30,11 +30,11 @@
  */

 class JpaLocalTxnInterceptor implements MethodInterceptor {

 

-  @Inject // Dirty hack =(

-  private final EntityManagerProvider emProvider = null;

+  @Inject

+  private final JpaPersistService emProvider = null;

 

-  @Inject // Dirty hack =(

-  private final WorkManager workManager = null;

+  @Inject

+  private final UnitOfWork unitOfWork = null;

 

   @Transactional

   private static class Internal {}

@@ -50,8 +50,6 @@
       didWeStartWork.set(true);

     }

 

-    // TODO(dhanji): Should we make this work with other annotations?

-    // TODO(dhanji): Cache this result by method?

     Transactional transactional = readTransactionMetadata(methodInvocation);

     EntityManager em = this.emProvider.get();

 

@@ -79,7 +77,7 @@
       // Close the em if necessary (guarded so this code doesn't run unless catch fired).

       if (null != didWeStartWork.get() && !txn.isActive()) {

         didWeStartWork.remove();

-        workManager.end();

+        unitOfWork.end();

       }

     }

 

@@ -91,7 +89,7 @@
       //close the em if necessary

       if (null != didWeStartWork.get() ) {

         didWeStartWork.remove();

-        workManager.end();

+        unitOfWork.end();

       }

     }

 

@@ -119,10 +117,11 @@
   }

 

   /**

+   * Returns True if rollback DID NOT HAPPEN (i.e. if commit should continue).

+   *

    * @param transactional The metadata annotaiton of the method

    * @param e The exception to test for rollback

    * @param txn A JPA Transaction to issue rollbacks on

-   * @return returns True if rollback DID NOT HAPPEN (i.e. if commit should continue).

    */

   private boolean rollbackIfNecessary(Transactional transactional, Exception e,

       EntityTransaction txn) {

diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
index 624bbaf..26da719 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistModule.java
@@ -1,11 +1,27 @@
+/**
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.persist.jpa;
 
 import com.google.inject.Singleton;
 import com.google.inject.internal.util.Preconditions;
 import com.google.inject.persist.PersistModule;
-import com.google.inject.persist.WorkManager;
+import com.google.inject.persist.PersistService;
+import com.google.inject.persist.UnitOfWork;
 import com.google.inject.util.Providers;
-import java.lang.annotation.Annotation;
 import java.util.Properties;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
@@ -13,55 +29,43 @@
 
 /**
  * JPA provider for guice persist.
+ *
+ * @author dhanji@gmail.com (Dhanji R. Prasanna)
  */
 public final class JpaPersistModule extends PersistModule {
   private final String jpaUnit;
 
   public JpaPersistModule(String jpaUnit) {
     Preconditions.checkArgument(null != jpaUnit && !jpaUnit.isEmpty(),
-        "Specified JPA unit name must be a non-empty string.");
+        "JPA unit name must be a non-empty string.");
     this.jpaUnit = jpaUnit;
   }
 
-  public JpaPersistModule(String jpaUnit, Class<? extends Annotation> unitOfWork) {
-    this(jpaUnit);
-    setUnitOfWork(unitOfWork);
-  }
-
-  public JpaPersistModule(String jpaUnit, Class<? extends Annotation> unitOfWork,
-      Class<? extends Annotation> transactional) {
-    this(jpaUnit);
-    setUnitOfWork(unitOfWork);
-    setTransactional(transactional);
-  }
-
   private Properties properties;
-  private final MethodInterceptor transactionInterceptor = new JpaLocalTxnInterceptor();
+  private MethodInterceptor transactionInterceptor;
 
   @Override protected void configurePersistence() {
-    bindConstant().annotatedWith(PersistModule.Persist.class).to(jpaUnit);
+    bindConstant().annotatedWith(Jpa.class).to(jpaUnit);
 
     if (null != properties) {
-      bind(Properties.class).annotatedWith(PersistModule.Persist.class).toInstance(properties);
+      bind(Properties.class).annotatedWith(Jpa.class).toInstance(properties);
     } else {
-      bind(Properties.class).annotatedWith(PersistModule.Persist.class)
+      bind(Properties.class).annotatedWith(Jpa.class)
           .toProvider(Providers.<Properties>of(null));
     }
 
-    bind(EntityManagerProvider.class).in(Singleton.class);
-    bind(EntityManagerProvider.EntityManagerFactoryProvider.class).in(Singleton.class);
+    bind(JpaPersistService.class).in(Singleton.class);
 
-    bind(EntityManager.class).toProvider(EntityManagerProvider.class);
+    bind(PersistService.class).to(JpaPersistService.class);
+    bind(UnitOfWork.class).to(JpaPersistService.class);
+    bind(EntityManager.class).toProvider(JpaPersistService.class);
     bind(EntityManagerFactory.class)
-        .toProvider(EntityManagerProvider.EntityManagerFactoryProvider.class);
+        .toProvider(JpaPersistService.EntityManagerFactoryProvider.class);
 
+    transactionInterceptor = new JpaLocalTxnInterceptor();
     requestInjection(transactionInterceptor);
   }
 
-  @Override protected Class<? extends WorkManager> getWorkManager() {
-    return EntityManagerProvider.class;
-  }
-
   @Override protected MethodInterceptor getTransactionInterceptor() {
     return transactionInterceptor;
   }
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/EntityManagerProvider.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
similarity index 81%
rename from extensions/persist/src/com/google/inject/persist/jpa/EntityManagerProvider.java
rename to extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
index 7058d9a..cf52a9d 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/EntityManagerProvider.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaPersistService.java
@@ -21,8 +21,8 @@
 import com.google.inject.Singleton;

 import com.google.inject.internal.Nullable;

 import com.google.inject.internal.util.Preconditions;

-import com.google.inject.persist.PersistModule;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.PersistService;

+import com.google.inject.persist.UnitOfWork;

 import java.util.Properties;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

@@ -32,15 +32,15 @@
  * @author Dhanji R. Prasanna (dhanji@gmail.com)

  */

 @Singleton

-class EntityManagerProvider implements Provider<EntityManager>, WorkManager {

+class JpaPersistService implements Provider<EntityManager>, UnitOfWork, PersistService {

   private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();

 

   private final String persistenceUnitName;

   private final Properties persistenceProperties;

 

   @Inject

-  public EntityManagerProvider(@PersistModule.Persist String persistenceUnitName,

-      @Nullable @PersistModule.Persist Properties persistenceProperties) {

+  public JpaPersistService(@Jpa String persistenceUnitName,

+      @Nullable @Jpa Properties persistenceProperties) {

     this.persistenceUnitName = persistenceUnitName;

     this.persistenceProperties = persistenceProperties;

   }

@@ -52,7 +52,7 @@
 

     EntityManager em = entityManager.get();

     Preconditions.checkState(null != em, "Requested EntityManager outside work unit. "

-        + "Try calling WorkManager.begin() first, or use a PersistenceFilter if you "

+        + "Try calling UnitOfWork.begin() first, or use a PersistFilter if you "

         + "are inside a servlet environment.");

 

     return em;

@@ -64,7 +64,7 @@
 

   public void begin() {

     Preconditions.checkState(null == entityManager.get(),

-        "Work already begun on this thread. Looks like you have called WorkManager.begin() twice"

+        "Work already begun on this thread. Looks like you have called UnitOfWork.begin() twice"

          + " without a balancing call to end() in between.");

 

     entityManager.set(emFactory.createEntityManager());

@@ -84,7 +84,7 @@
 

   private volatile EntityManagerFactory emFactory;

 

-  public synchronized void startPersistence() {

+  public synchronized void start() {

     Preconditions.checkState(null == emFactory, "Persistence service was already initialized.");

 

     if (null != persistenceProperties) {

@@ -95,17 +95,17 @@
     }

   }

 

-  public synchronized void shutdownPersistence() {

+  public synchronized void stop() {

     Preconditions.checkState(emFactory.isOpen(), "Persistence service was already shut down.");

     emFactory.close();

   }

 

   @Singleton

   public static class EntityManagerFactoryProvider implements Provider<EntityManagerFactory> {

-    private final EntityManagerProvider emProvider;

+    private final JpaPersistService emProvider;

 

     @Inject

-    public EntityManagerFactoryProvider(EntityManagerProvider emProvider) {

+    public EntityManagerFactoryProvider(JpaPersistService emProvider) {

       this.emProvider = emProvider;

     }

 

diff --git a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
index d452e0d..7a55893 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
@@ -1,4 +1,4 @@
 /**
- * guice Persist's Java Persistence API (JPA) support.
+ * guice-persist's Java Persistence API (JPA) support.
  */
 package com.google.inject.persist.jpa;
\ No newline at end of file
diff --git a/extensions/persist/src/com/google/inject/persist/package-info.java b/extensions/persist/src/com/google/inject/persist/package-info.java
index 8da2951..43cda2a 100644
--- a/extensions/persist/src/com/google/inject/persist/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/package-info.java
@@ -1,4 +1,4 @@
 /**
- * Guice Persist, a lightweight persistence library for Guice.
+ * Guice Persist: a lightweight persistence library for Guice.
  */
 package com.google.inject.persist;
\ No newline at end of file
diff --git a/extensions/persist/test/com/google/inject/persist/EdslTest.java b/extensions/persist/test/com/google/inject/persist/EdslTest.java
index 138dee8..b1d4b0e 100644
--- a/extensions/persist/test/com/google/inject/persist/EdslTest.java
+++ b/extensions/persist/test/com/google/inject/persist/EdslTest.java
@@ -10,7 +10,7 @@
  */
 public class EdslTest extends TestCase {
 
-  public void testModuleConfig() throws Exception {
+  public void testModuleConfigUsingJpa() throws Exception {
     new InjectorBuilder()
         .addModules(new JpaPersistModule("myunit"))
         .stage(Stage.PRODUCTION)
diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
index aea192d..f66cdb3 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ClassLevelManagedLocalTransactionsTest.java
@@ -19,8 +19,8 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

 import java.io.FileNotFoundException;

 import java.io.IOException;

 import java.util.Date;

@@ -47,11 +47,11 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   public void tearDown() {

-    injector.getInstance(WorkManager.class).shutdownPersistence();

+    injector.getInstance(PersistService.class).stop();

     injector = null;

   }

 

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
index cb97988..18f8932 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/CustomPropsEntityManagerFactoryProvisionTest.java
@@ -18,7 +18,8 @@
 

 import com.google.inject.Guice;

 import com.google.inject.Injector;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.PersistService;

+import com.google.inject.persist.UnitOfWork;

 import java.util.Properties;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

@@ -40,18 +41,18 @@
 

   @Override

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

     injector.getInstance(EntityManagerFactory.class).close();

   }

 

   public void testSessionCreateOnInjection() {

 

-    assertEquals("SINGLETON VIOLATION " + WorkManager.class.getName(),

-        injector.getInstance(WorkManager.class),

-        injector.getInstance(WorkManager.class));

+    assertEquals("SINGLETON VIOLATION " + UnitOfWork.class.getName(),

+        injector.getInstance(UnitOfWork.class),

+        injector.getInstance(UnitOfWork.class));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

 

     //obtain em

     assertTrue(injector.getInstance(EntityManager.class).isOpen());

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
index d245cc3..3a6786e 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerFactoryProvisionTest.java
@@ -18,7 +18,8 @@
 

 import com.google.inject.Guice;

 import com.google.inject.Injector;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.PersistService;

+import com.google.inject.persist.UnitOfWork;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

 import junit.framework.TestCase;

@@ -34,18 +35,18 @@
   }

 

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

     injector.getInstance(EntityManagerFactory.class).close();

   }

 

   public void testSessionCreateOnInjection() {

 

-    assertTrue("SINGLETON VIOLATION " + WorkManager.class.getName(),

-        injector.getInstance(WorkManager.class)

-        .equals(injector.getInstance(WorkManager.class)));

+    assertTrue("SINGLETON VIOLATION " + UnitOfWork.class.getName(),

+        injector.getInstance(UnitOfWork.class)

+        .equals(injector.getInstance(UnitOfWork.class)));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

 

     //obtain em

     assertTrue(injector.getInstance(EntityManager.class).isOpen());

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
index 4526b94..50c13da 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerPerRequestProvisionTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

 import junit.framework.TestCase;

@@ -38,14 +39,14 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

 

-    injector.getInstance(WorkManager.class).begin();

+    injector.getInstance(UnitOfWork.class).begin();

   }

 

   @Override

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

     injector.getInstance(EntityManagerFactory.class).close();

   }

 

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
index 8cd7526..a477160 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/EntityManagerProvisionTest.java
@@ -20,8 +20,8 @@
 import com.google.inject.Inject;

 import com.google.inject.Injector;

 import com.google.inject.Provider;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

 import junit.framework.TestCase;

@@ -38,7 +38,7 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   public final void tearDown() {

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
index 54a6dba..74aba3b 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JoiningLocalTransactionsTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import java.io.IOException;

 import java.util.Date;

 import javax.persistence.EntityManager;

@@ -43,13 +44,13 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   //cleanup entitymanager in case some of the rollback tests left it in an open state

   @Override

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

     injector.getInstance(EntityManagerFactory.class).close();

   }

 

@@ -64,7 +65,7 @@
     //test that the data has been stored

     Object result = em.createQuery("from JpaTestEntity where text = :text")

         .setParameter("text", UNIQUE_TEXT).getSingleResult();

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);

 

@@ -78,7 +79,7 @@
           .runOperationInTxnThrowingChecked();

     } catch (IOException e) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -90,7 +91,7 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail("a result was returned! rollback sure didnt happen!!!");

     } catch (NoResultException e) { }

   }

@@ -101,7 +102,7 @@
           .runOperationInTxnThrowingUnchecked();

     } catch (RuntimeException re) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -111,7 +112,7 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail("a result was returned! rollback sure didnt happen!!!");

     } catch (NoResultException e) {}

   }

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java b/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
index c68a422..13049d6 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/JpaWorkManagerTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import java.util.Date;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

@@ -40,7 +41,7 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   @Override

@@ -49,15 +50,15 @@
   }

 

   public void testWorkManagerInSession() {

-    injector.getInstance(WorkManager.class).begin();

+    injector.getInstance(UnitOfWork.class).begin();

     try {

       injector.getInstance(TransactionalObject.class).runOperationInTxn();

     } finally {

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

 

     }

 

-    injector.getInstance(WorkManager.class).begin();

+    injector.getInstance(UnitOfWork.class).begin();

     injector.getInstance(EntityManager.class).getTransaction().begin();

     try {

       final Query query = injector.getInstance(EntityManager.class)

@@ -75,15 +76,15 @@
 

     } finally {

       injector.getInstance(EntityManager.class).getTransaction().commit();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

   }

 

   public void testCloseMoreThanOnce() {

-    injector.getInstance(WorkManager.class).shutdownPersistence();

+    injector.getInstance(PersistService.class).stop();

 

     try {

-      injector.getInstance(WorkManager.class).shutdownPersistence();

+      injector.getInstance(PersistService.class).stop();

       fail();

     } catch (IllegalStateException e) {

       // Ignored.

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
index cc9a3fd..3934d3b 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsAcrossRequestTest.java
@@ -20,8 +20,9 @@
 import com.google.inject.Inject;

 import com.google.inject.Injector;

 import com.google.inject.name.Named;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import com.google.inject.persist.finder.Finder;

 import java.io.IOException;

 import java.util.Date;

@@ -46,7 +47,7 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   @Override

@@ -63,13 +64,13 @@
     //test that the data has been stored

     Object result = em.createQuery("from JpaTestEntity where text = :text")

         .setParameter("text", UNIQUE_TEXT).getSingleResult();

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);

 

     assertEquals("queried entity did not match--did automatic txn fail?",

         UNIQUE_TEXT, ((JpaTestEntity) result).getText());

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

   }

 

@@ -90,13 +91,13 @@
 

     Object result = em.createQuery("from JpaTestEntity where text = :text")

         .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult();

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertTrue(result instanceof JpaTestEntity);

 

     assertEquals("queried entity did not match--did automatic txn fail?",

         UNIQUE_TEXT_MERGE, ((JpaTestEntity) result).getText());

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

   }

 

@@ -114,14 +115,14 @@
     assertTrue("Merge did not store state or did not return persistent copy", em.contains(entity));

 

     Object result = injector.getInstance(TransactionalObject.class).find(UNIQUE_TEXT_MERGE_FORDF);

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertNotNull(result);

     assertTrue(result instanceof JpaTestEntity);

 

     assertEquals("queried entity did not match--did automatic txn fail?",

         UNIQUE_TEXT_MERGE_FORDF, ((JpaTestEntity) result).getText());

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

   }

 

@@ -130,7 +131,7 @@
       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingChecked();

     } catch (IOException e) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -142,11 +143,11 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail();

     } catch (NoResultException e) {}

 

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

   }

 

   public void testSimpleTransactionRollbackOnUnchecked() {

@@ -154,7 +155,7 @@
       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingUnchecked();

     } catch (RuntimeException re) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -164,11 +165,11 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail();

     } catch (NoResultException e) {}

     

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

   }

 

   public static class TransactionalObject {

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
index 2432015..9707dd1 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManagedLocalTransactionsTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import java.io.IOException;

 import java.util.Date;

 import javax.persistence.EntityManager;

@@ -42,12 +43,12 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   @Override

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

     injector.getInstance(EntityManagerFactory.class).close();

   }

 

@@ -60,7 +61,7 @@
     //test that the data has been stored

     Object result = em.createQuery("from JpaTestEntity where text = :text")

         .setParameter("text", UNIQUE_TEXT).getSingleResult();

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertTrue("odd result returned fatal", result instanceof JpaTestEntity);

 

@@ -80,7 +81,7 @@
 

     Object result = em.createQuery("from JpaTestEntity where text = :text")

         .setParameter("text", UNIQUE_TEXT_MERGE).getSingleResult();

-    injector.getInstance(WorkManager.class).end();

+    injector.getInstance(UnitOfWork.class).end();

 

     assertTrue(result instanceof JpaTestEntity);

 

@@ -93,7 +94,7 @@
       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingChecked();

     } catch (IOException e) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -105,7 +106,7 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail("a result was returned! rollback sure didnt happen!!!");

     } catch (NoResultException e) {}

   }

@@ -115,7 +116,7 @@
       injector.getInstance(TransactionalObject.class).runOperationInTxnThrowingUnchecked();

     } catch (RuntimeException re) {

       //ignore

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

     }

 

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -125,7 +126,7 @@
     try {

       Object result = em.createQuery("from JpaTestEntity where text = :text")

           .setParameter("text", TRANSIENT_UNIQUE_TEXT).getSingleResult();

-      injector.getInstance(WorkManager.class).end();

+      injector.getInstance(UnitOfWork.class).end();

       fail("a result was returned! rollback sure didnt happen!!!");

     } catch (NoResultException e) {}

   }

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
index fdbe48a..c0a8f80 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsConfidenceTest.java
@@ -19,8 +19,8 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

 import java.util.Date;

 import javax.persistence.EntityManager;

 import javax.persistence.PersistenceException;

@@ -40,12 +40,12 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   @Override

   public final void tearDown() {

-    injector.getInstance(WorkManager.class).shutdownPersistence();

+    injector.getInstance(PersistService.class).stop();

   }

 

   public void testThrowingCleanupInterceptorConfidence() {

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
index 7a0534b..8034076 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;

 import com.google.inject.Inject;

 import com.google.inject.Injector;

+import com.google.inject.persist.PersistService;

 import com.google.inject.persist.Transactional;

-import com.google.inject.persist.WorkManager;

+import com.google.inject.persist.UnitOfWork;

 import java.util.Date;

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

@@ -41,7 +42,7 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));

 

     //startup persistence

-    injector.getInstance(WorkManager.class).startPersistence();

+    injector.getInstance(PersistService.class).start();

   }

 

   public void tearDown() {

@@ -49,7 +50,7 @@
   }

 

   public void testSimpleCrossTxnWork() {

-    injector.getInstance(WorkManager.class).begin();

+    injector.getInstance(UnitOfWork.class).begin();

 

     //pretend that the request was started here

     EntityManager em = injector.getInstance(EntityManager.class);

@@ -63,8 +64,8 @@
     assertTrue("EntityManager  appears to have been closed across txns!", em.contains(entity));

     assertTrue("EntityManager appears to have been closed across txns!", em.isOpen());

 

-    injector.getInstance(WorkManager.class).end();

-    injector.getInstance(WorkManager.class).begin();

+    injector.getInstance(UnitOfWork.class).end();

+    injector.getInstance(UnitOfWork.class).begin();

 

     //try to query them back out

     em = injector.getInstance(EntityManager.class);

diff --git a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
index d20a871..7fedb86 100644
--- a/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
+++ b/extensions/persist/test/com/google/inject/persist/jpa/ManualLocalTransactionsWithCustomMatcherTest.java
@@ -19,8 +19,9 @@
 import com.google.inject.Guice;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 import com.google.inject.persist.Transactional;
-import com.google.inject.persist.WorkManager;
+import com.google.inject.persist.UnitOfWork;
 import java.util.Date;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
@@ -45,7 +46,7 @@
     injector = Guice.createInjector(new JpaPersistModule("testUnit"));
 
     //startup persistence
-    injector.getInstance(WorkManager.class).startPersistence();
+    injector.getInstance(PersistService.class).start();
   }
 
   @Override
@@ -69,7 +70,7 @@
     assertTrue("EntityManager  appears to have been closed across txns!", em.contains(entity));
     assertTrue("EntityManager appears to have been closed across txns!", em.isOpen());
 
-    injector.getInstance(WorkManager.class).end();
+    injector.getInstance(UnitOfWork.class).end();
 
     //try to query them back out
     em = injector.getInstance(EntityManager.class);