/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * PersistenceManager.java
 *
 */
package javax.jdo;

import java.util.Collection;
import java.util.Date;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import javax.jdo.datastore.JDOConnection;
import javax.jdo.datastore.Sequence;
import javax.jdo.listener.InstanceLifecycleListener;

/**
 * <code>PersistenceManager</code> is the primary interface for JDO-aware application components. It
 * is the factory for <code>Query</code> and <code>Transaction</code> instances, and contains
 * methods to manage the life cycle of <code>PersistenceCapable</code> instances.
 *
 * <p>A <code>PersistenceManager</code> is obtained from the {@link PersistenceManagerFactory}
 * (recommended) or by construction.
 *
 * @version 2.1
 */
public interface PersistenceManager extends AutoCloseable {
  /**
   * A <code>PersistenceManager</code> instance can be used until it is closed.
   *
   * @return <code>true</code> if this <code>PersistenceManager</code> has been closed.
   * @see #close()
   */
  boolean isClosed();

  /**
   * Close this <code>PersistenceManager</code> so that no further requests may be made on it. A
   * <code>PersistenceManager</code> instance can be used only until it is closed.
   *
   * <p>Closing a <code>PersistenceManager</code> might release it to the pool of available <code>
   * PersistenceManager</code>s, or might be garbage collected, at the option of the JDO
   * implementation. Before being used again to satisfy a <code>getPersistenceManager()</code>
   * request, the default values for options will be restored to their values as specified in the
   * <code>PersistenceManagerFactory</code>.
   *
   * <p>This method closes the <code>PersistenceManager</code>.
   */
  void close();

  /**
   * Return the <code>Transaction</code> instance associated with a <code>PersistenceManager</code>.
   * There is one <code>Transaction</code> instance associated with each <code>PersistenceManager
   * </code> instance. The <code>Transaction</code> instance supports options as well as transaction
   * completion requests.
   *
   * @return the <code>Transaction</code> associated with this <code>PersistenceManager</code>.
   */
  Transaction currentTransaction();

  /**
   * Mark an instance as no longer needed in the cache. Eviction is normally done automatically by
   * the <code>PersistenceManager</code> at transaction completion. This method allows the
   * application to explicitly provide a hint to the <code>PersistenceManager</code> that the
   * instance is no longer needed in the cache.
   *
   * @param pc the instance to evict from the cache.
   */
  void evict(Object pc);

  /**
   * Mark an array of instances as no longer needed in the cache.
   *
   * @see #evict(Object pc)
   * @param pcs the array of instances to evict from the cache.
   */
  void evictAll(Object... pcs);

  /**
   * Mark a <code>Collection</code> of instances as no longer needed in the cache.
   *
   * @see #evict(Object pc)
   * @param pcs the <code>Collection</code> of instances to evict from the cache.
   */
  void evictAll(Collection<?> pcs);

  /**
   * Mark the parameter instances as no longer needed in the cache.
   *
   * @param pcClass the class of instances to evict
   * @param subclasses if true, mark instances of subclasses also
   * @since 2.1
   */
  void evictAll(boolean subclasses, Class<?> pcClass);

  /**
   * Mark all persistent-nontransactional instances as no longer needed in the cache. It transitions
   * all persistent-nontransactional instances to hollow. Transactional instances are subject to
   * eviction based on the RetainValues setting.
   *
   * @see #evict(Object pc)
   */
  void evictAll();

  /**
   * Refresh the state of the instance from the data store.
   *
   * <p>In an optimistic transaction, the state of instances in the cache might not match the state
   * in the data store. This method is used to reload the state of the instance from the data store
   * so that a subsequent commit is more likely to succeed.
   *
   * <p>Outside a transaction, this method will refresh nontransactional state.
   *
   * @param pc the instance to refresh.
   */
  void refresh(Object pc);

  /**
   * Refresh the state of an array of instances from the data store.
   *
   * @see #refresh(Object pc)
   * @param pcs the array of instances to refresh.
   */
  void refreshAll(Object... pcs);

  /**
   * Refresh the state of a <code>Collection</code> of instances from the data store.
   *
   * @see #refresh(Object pc)
   * @param pcs the <code>Collection</code> of instances to refresh.
   */
  void refreshAll(Collection<?> pcs);

  /**
   * Refresh the state of all applicable instances from the data store.
   *
   * <p>If called with an active transaction, all transactional instances will be refreshed. If
   * called outside an active transaction, all nontransactional instances will be refreshed.
   *
   * @see #refresh(Object pc)
   */
  void refreshAll();

  /**
   * Refreshes all instances in the exception that failed verification.
   *
   * @param jdoe The exception defining object(s) to be refreshed
   * @since 2.0
   */
  void refreshAll(JDOException jdoe);

  /**
   * Create a new <code>Query</code> with no elements.
   *
   * @return the new <code>Query</code>.
   */
  Query newQuery();

  /**
   * Create a new <code>Query</code> using elements from another <code>Query</code>. The other
   * <code>Query</code> must have been created by the same JDO implementation. It might be active in
   * a different <code>PersistenceManager</code> or might have been serialized and restored.
   *
   * <p>All of the settings of the other <code>Query</code> are copied to this <code>Query</code>,
   * except for the candidate <code>Collection</code> or <code>Extent</code>.
   *
   * @return the new <code>Query</code>
   * @param compiled another <code>Query</code> from the same JDO implementation
   */
  Query newQuery(Object compiled);

  /**
   * Create a Construct a new query instance using the specified String as the single-string
   * representation of the query.
   *
   * @param query the single-string query
   * @return the new <code>Query</code>
   * @since 2.0
   */
  Query newQuery(String query);

  /**
   * Create a new <code>Query</code> using the specified language.
   *
   * @param language the language of the query parameter
   * @param query the query, which is of a form determined by the language
   * @return the new <code>Query</code>
   */
  Query newQuery(String language, Object query);

  /**
   * Create a new <code>Query</code> specifying the <code>Class</code> of the candidate instances.
   *
   * @param cls the <code>Class</code> of the candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Class<T> cls);

  /**
   * Create a new <code>Query</code> with the <code>Class</code> of the candidate instances and
   * candidate <code>Extent</code>.
   *
   * @param cln the <code>Extent</code> of candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Extent<T> cln);

  /**
   * Create a new <code>Query</code> with the candidate <code>Class</code> and <code>Collection
   * </code>.
   *
   * @param cls the <code>Class</code> of results
   * @param cln the <code>Collection</code> of candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Class<T> cls, Collection<T> cln);

  /**
   * Create a new <code>Query</code> with the <code>Class</code> of the candidate instances and
   * filter.
   *
   * @param cls the <code>Class</code> of results
   * @param filter the filter for candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Class<T> cls, String filter);

  /**
   * Create a new <code>Query</code> with the <code>Class</code> of the candidate instances,
   * candidate <code>Collection</code>, and filter.
   *
   * @param cls the <code>Class</code> of candidate instances
   * @param cln the <code>Collection</code> of candidate instances
   * @param filter the filter for candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Class<T> cls, Collection<T> cln, String filter);

  /**
   * Create a new <code>Query</code> with the candidate <code>Extent</code> and filter; the class is
   * taken from the <code>Extent</code>.
   *
   * @param cln the <code>Extent</code> of candidate instances
   * @param filter the filter for candidate instances
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newQuery(Extent<T> cln, String filter);

  /**
   * Create a new <code>JDOQLTypedQuery</code> with the specified candidate class.
   *
   * @param cls Candidate class for the query
   * @return The JDOQLTypedQuery
   * @param <T> Candidate type for the query
   * @since 3.2
   */
  <T> JDOQLTypedQuery<T> newJDOQLTypedQuery(Class<T> cls);

  /**
   * Create a new <code>Query</code> with the given candidate class from a named query. The query
   * name given must be the name of a query defined in metadata.
   *
   * @param cls the <code>Class</code> of candidate instances
   * @param queryName the name of the query to look up in metadata
   * @return the new <code>Query</code>
   * @param <T> Candidate type for the query
   */
  <T> Query<T> newNamedQuery(Class<T> cls, String queryName);

  /**
   * The <code>PersistenceManager</code> manages a collection of instances in the data store based
   * on the class of the instances. This method returns an <code>Extent</code> of instances in the
   * data store that might be iterated or given to a <code>Query</code>. The <code>Extent</code>
   * itself might not reference any instances, but only hold the class name and an indicator as to
   * whether subclasses are included in the <code>Extent</code>.
   *
   * <p>Note that the <code>Extent</code> might be very large.
   *
   * @param persistenceCapableClass <code>Class</code> of instances
   * @param subclasses whether to include instances of subclasses
   * @return an <code>Extent</code> of the specified <code>Class</code>
   * @see Query
   * @param <T> Type for the candidate of the Extent
   */
  <T> Extent<T> getExtent(Class<T> persistenceCapableClass, boolean subclasses);

  /**
   * Equivalent to <code>getExtent (persistenceCapableClass, true)</code>.
   *
   * @see #getExtent(Class,boolean)
   * @since 2.0
   * @param persistenceCapableClass Candidate class for the extent
   * @return an <code>Extent</code> of the specified <code>Class</code>
   * @param <T> Type for the candidate of the Extent
   */
  <T> Extent<T> getExtent(Class<T> persistenceCapableClass);

  /**
   * This method locates a persistent instance in the cache of instances managed by this <code>
   * PersistenceManager</code>. The <code>getObjectById</code> method attempts to find an instance
   * in the cache with the specified JDO identity. The <code>oid</code> parameter object might have
   * been returned by an earlier call to <code>getObjectId</code> or <code>getTransactionalObjectId
   * </code>, or might have been constructed by the application.
   *
   * <p>If the <code>PersistenceManager</code> is unable to resolve the <code>oid</code> parameter
   * to an ObjectId instance, then it throws a <code>JDOUserException</code>.
   *
   * <p>If the <code>validate</code> flag is <code>false</code>, and there is already an instance in
   * the cache with the same JDO identity as the <code>oid</code> parameter, then this method
   * returns it. There is no change made to the state of the returned instance.
   *
   * <p>If there is not an instance already in the cache with the same JDO identity as the <code>oid
   * </code> parameter, then this method creates an instance with the specified JDO identity and
   * returns it. If there is no transaction in progress, the returned instance will be hollow or
   * persistent-nontransactional, at the choice of the implementation.
   *
   * <p>If there is a transaction in progress, the returned instance will be hollow,
   * persistent-nontransactional, or persistent-clean, at the choice of the implementation.
   *
   * <p>It is an implementation decision whether to access the data store, if required to determine
   * the exact class. This will be the case of inheritance, where multiple <code>PersistenceCapable
   * </code> classes share the same ObjectId class.
   *
   * <p>If the validate flag is <code>false</code>, and the instance does not exist in the data
   * store, then this method might not fail. It is an implementation choice whether to fail
   * immediately with a <code>JDOObjectNotFoundException</code>. But a subsequent access of the
   * fields of the instance will throw a <code>JDOObjectNotFoundException</code> if the instance
   * does not exist at that time. Further, if a relationship is established to this instance, then
   * the transaction in which the association was made will fail.
   *
   * <p>If the <code>validate</code> flag is <code>true</code>, and there is already a transactional
   * instance in the cache with the same JDO identity as the <code>oid</code> parameter, then this
   * method returns it. There is no change made to the state of the returned instance.
   *
   * <p>If there is an instance already in the cache with the same JDO identity as the <code>oid
   * </code> parameter, but the instance is not transactional, then it must be verified in the data
   * store. If the instance does not exist in the datastore, then a <code>JDOObjectNotFoundException
   * </code> is thrown.
   *
   * <p>If there is not an instance already in the cache with the same JDO identity as the <code>oid
   * </code> parameter, then this method creates an instance with the specified JDO identity,
   * verifies that it exists in the data store, and returns it. If there is no transaction in
   * progress, the returned instance will be hollow or persistent-nontransactional, at the choice of
   * the implementation.
   *
   * <p>If there is a data store transaction in progress, the returned instance will be
   * persistent-clean. If there is an optimistic transaction in progress, the returned instance will
   * be persistent-nontransactional.
   *
   * @see #getObjectId(Object pc)
   * @see #getTransactionalObjectId(Object pc)
   * @return the <code>PersistenceCapable</code> instance with the specified ObjectId
   * @param oid an ObjectId
   * @param validate if the existence of the instance is to be validated
   */
  Object getObjectById(Object oid, boolean validate);

  /**
   * Looks up the instance of the given type with the given key.
   *
   * @param cls The type of object to load
   * @param key either the string representation of the object id, or an object representation of a
   *     single field identity key
   * @return the corresponding persistent instance
   * @since 2.0
   * @param <T> Type of the persistable object being retrieved
   */
  <T> T getObjectById(Class<T> cls, Object key);

  /**
   * Looks up the instance corresponding to the specified oid. This is equivalent to <code>
   * getObjectById(oid, true);</code>
   *
   * @param oid The object id of the object to load
   * @return the corresponding persistent instance
   */
  Object getObjectById(Object oid);

  /**
   * The ObjectId returned by this method represents the JDO identity of the instance. The ObjectId
   * is a copy (clone) of the internal state of the instance, and changing it does not affect the
   * JDO identity of the instance.
   *
   * <p>The <code>getObjectId</code> method returns an ObjectId instance that represents the object
   * identity of the specified JDO instance. The identity is guaranteed to be unique only in the
   * context of the JDO <code>PersistenceManager</code> that created the identity, and only for two
   * types of JDO Identity: those that are managed by the application, and those that are managed by
   * the data store.
   *
   * <p>If the object identity is being changed in the transaction, by the application modifying one
   * or more of the application key fields, then this method returns the identity as of the
   * beginning of the transaction. The value returned by <code>getObjectId</code> will be different
   * following <code>afterCompletion</code> processing for successful transactions.
   *
   * <p>Within a transaction, the ObjectId returned will compare equal to the ObjectId returned by
   * only one among all JDO instances associated with the <code>PersistenceManager</code> regardless
   * of the type of ObjectId.
   *
   * <p>The ObjectId does not necessarily contain any internal state of the instance, nor is it
   * necessarily an instance of the class used to manage identity internally. Therefore, if the
   * application makes a change to the ObjectId instance returned by this method, there is no effect
   * on the instance from which the ObjectId was obtained.
   *
   * <p>The <code>getObjectById</code> method can be used between instances of <code>
   * PersistenceManager</code> of different JDO vendors only for instances of persistence capable
   * classes using application-managed (primary key) JDO identity. If it is used for instances of
   * classes using datastore identity, the method might succeed, but there are no guarantees that
   * the parameter and return instances are related in any way.
   *
   * @see #getTransactionalObjectId(Object pc)
   * @see #getObjectById(Object oid, boolean validate)
   * @param pc the <code>PersistenceCapable</code> instance
   * @return the ObjectId of the instance
   */
  Object getObjectId(Object pc);

  /**
   * The ObjectId returned by this method represents the JDO identity of the instance. The ObjectId
   * is a copy (clone) of the internal state of the instance, and changing it does not affect the
   * JDO identity of the instance.
   *
   * <p>If the object identity is being changed in the transaction, by the application modifying one
   * or more of the application key fields, then this method returns the current identity in the
   * transaction.
   *
   * <p>If there is no transaction in progress, or if none of the key fields is being modified, then
   * this method will return the same value as <code>getObjectId</code>.
   *
   * @see #getObjectId(Object pc)
   * @see #getObjectById(Object oid, boolean validate)
   * @param pc a <code>PersistenceCapable</code> instance
   * @return the ObjectId of the instance
   */
  Object getTransactionalObjectId(Object pc);

  /**
   * This method returns an object id instance corresponding to the pcClass and key arguments.
   *
   * @param pcClass the <code>Class</code> of the persistence-capable instance
   * @param key for single-field identity, the parameter for the constructor; for non-single-field
   *     application identity, the result of toString() on the object id instance.
   * @return an instance of the object identity class
   */
  Object newObjectIdInstance(Class<?> pcClass, Object key);

  /**
   * Return the objects with the given oids.
   *
   * @param oids the oids of the objects to return
   * @param validate if true, the existance of the objects in the datastore will be validated.
   * @return the objects that were looked up, in the same order as the oids parameter.
   * @see #getObjectById(Object,boolean)
   * @since 2.0
   */
  Collection getObjectsById(Collection<?> oids, boolean validate);

  /**
   * Return the objects with the given oids. This method is equivalent to calling {@link
   * #getObjectsById(Collection, boolean)} with the validate flag true.
   *
   * @param oids the oids of the objects to return
   * @return the objects that were looked up, in the same order as the oids parameter.
   * @see #getObjectsById(Collection,boolean)
   * @since 2.0
   */
  Collection getObjectsById(Collection<?> oids);

  /**
   * Return the objects with the given oids.
   *
   * @param oids the oids of the objects to return
   * @param validate if true, the existance of the objects in the datastore will be validated.
   * @return the objects that were looked up, in the same order as the oids parameter.
   * @see #getObjectById(Object,boolean)
   * @since 2.1
   */
  Object[] getObjectsById(boolean validate, Object... oids);

  /**
   * Return the objects with the given oids. This method is equivalent to calling {@link
   * #getObjectsById(boolean,Object...)} with the validate flag true.
   *
   * @param oids the oids of the objects to return
   * @return the objects that were looked up, in the same order as the oids parameter.
   * @see #getObjectsById(boolean,Object...)
   * @since 2.0
   */
  Object[] getObjectsById(Object... oids);

  /**
   * Make the parameter instance persistent in this <code>PersistenceManager</code>. This method
   * makes transient instances persistent and applies detached instance changes to the cache. It
   * must be called in the context of an active transaction, or a JDOUserException is thrown. For a
   * transient instance, it assigns an object identity to the instance and transitions it to
   * persistent-new. Any transient instances reachable from this instance via persistent fields of
   * this instance become provisionally persistent, transitively. That is, they behave as
   * persistent-new instances (return true to isPersistent, isNew, and isDirty). But at commit time,
   * the reachability algorithm is run again, and instances made provisionally persistent that are
   * not then reachable from persistent instances will revert to transient.
   *
   * <p>During makePersistent of transient instances, the create life cycle listener is called.
   *
   * <p>For detached instances, it locates or instantiates a persistent instance with the same JDO
   * identity as the detached instance, and merges the persistent state of the detached instance
   * into the persistent instance. Only the state of persistent fields is merged. If non-persistent
   * state needs to be copied, the application should use the jdoPostAttach callback or the
   * postAttach lifecycle event listener. Any references to the detached instances from instances in
   * the closure of the parameter instances are modified to refer to the corresponding persistent
   * instance instead of to the detached instance.
   *
   * <p>During attachment of detached instances, the attach callbacks and attach life cycle
   * listeners are called.
   *
   * <p>During application of changes of the detached state, if the JDO implementation can determine
   * that there were no changes made during detachment, then the implementation is not required to
   * mark the corresponding instance dirty. If it cannot determine if changes were made, then it
   * must mark the instance dirty. No consistency checking is done during makePersistent of detached
   * instances. If consistency checking is required by the application, then flush or
   * checkConsistency should be called after attaching the instances.
   *
   * <p>These methods have no effect on parameter persistent instances already managed by this
   * PersistenceManager. They will throw a JDOUserException if the parameter instance is managed by
   * a different PersistenceManager. If an instance is of a class whose identity type (application,
   * datastore, or none) is not supported by the JDO implementation, then a JDOUserException will be
   * thrown for that instance. The return value for parameter instances in the transient or
   * persistent states is the same as the parameter value. The return value for parameter instances
   * in the detached state is the persistent instance corresponding to the detached instance. The
   * return values for makePersistentAll methods correspond by position to the parameter instances.
   *
   * @param pc an instance of a <code>Class</code> that is persistent capable.
   * @return the parameter instance for parameters in the transient or persistent state, or the
   *     corresponding persistent instance for detached parameter instances
   * @param <T> Type of the persistable object
   */
  <T> T makePersistent(T pc);

  /**
   * Make an array of instances persistent.
   *
   * @param pcs an array of instances
   * @return the parameter instances for parameters in the transient or persistent state, or the
   *     corresponding persistent instance for detached parameter instances, in the same order as in
   *     the parameter array
   * @see #makePersistent(Object pc)
   * @param <T> Type of the persistable object
   */
  @SuppressWarnings({"unchecked", "varargs"})
  <T> T[] makePersistentAll(T... pcs);

  /**
   * Make a <code>Collection</code> of instances persistent.
   *
   * @param pcs a <code>Collection</code> of instances
   * @return the parameter instance for parameters in the transient or persistent state, or the
   *     corresponding persistent instance for detached parameter instances, with an iteration in
   *     the same order as in the parameter Collection
   * @see #makePersistent(Object pc)
   * @param <T> Type of the persistable object
   */
  <T> Collection<T> makePersistentAll(Collection<T> pcs);

  /**
   * Delete the persistent instance from the data store. This method must be called in an active
   * transaction. The data store object will be removed at commit. Unlike <code>makePersistent
   * </code>, which makes the closure of the instance persistent, the closure of the instance is not
   * deleted from the data store. This method has no effect if the instance is already deleted in
   * the current transaction. This method throws <code>JDOUserException</code> if the instance is
   * transient or is managed by another <code>PersistenceManager</code>.
   *
   * @param pc a persistent instance
   */
  void deletePersistent(Object pc);

  /**
   * Delete an array of instances from the data store.
   *
   * @param pcs a <code>Collection</code> of persistent instances
   * @see #deletePersistent(Object pc)
   */
  void deletePersistentAll(Object... pcs);

  /**
   * Delete a <code>Collection</code> of instances from the data store.
   *
   * @param pcs a <code>Collection</code> of persistent instances
   * @see #deletePersistent(Object pc)
   */
  void deletePersistentAll(Collection<?> pcs);

  /**
   * Make an instance transient, removing it from management by this <code>PersistenceManager</code>
   * .
   *
   * <p>The instance loses its JDO identity and it is no longer associated with any <code>
   * PersistenceManager</code>. The state of fields is preserved unchanged.
   *
   * @param pc the instance to make transient.
   */
  void makeTransient(Object pc);

  /**
   * Make an array of instances transient, removing them from management by this <code>
   * PersistenceManager</code>.
   *
   * <p>The instances lose their JDO identity and they are no longer associated with any <code>
   * PersistenceManager</code>. The state of fields is preserved unchanged.
   *
   * @param pcs the instances to make transient.
   */
  void makeTransientAll(Object... pcs);

  /**
   * Make a <code>Collection</code> of instances transient, removing them from management by this
   * <code>PersistenceManager</code>.
   *
   * <p>The instances lose their JDO identity and they are no longer associated with any <code>
   * PersistenceManager</code>. The state of fields is preserved unchanged.
   *
   * @param pcs the instances to make transient.
   */
  void makeTransientAll(Collection<?> pcs);

  /**
   * Make an instance transient, removing it from management by this <code>PersistenceManager</code>
   * . If the useFetchPlan parameter is false, this method behaves exactly as makeTransient(Object
   * pc).
   *
   * <p>The affected instance(s) lose their JDO identity and are no longer associated with any
   * <code>PersistenceManager</code>. The state of fields is unchanged.
   *
   * <p>If the useFetchPlan parameter is true, then the current FetchPlan is applied to the pc
   * parameter, as if detachCopy(Object) had been called. After the graph of instances is loaded,
   * the instances reachable via loaded fields is made transient. The state of fields in the
   * affected instances is as specified by the FetchPlan.
   *
   * <p>Unlike detachCopy, the instances are not detached; there is no detachment information in the
   * instances.
   *
   * <p>The instances to be made transient do not need to implement the javax.jdo.spi.Detachable
   * interface.
   *
   * @param pc the root instance to make transient.
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to make transient
   * @since 2.0
   */
  void makeTransient(Object pc, boolean useFetchPlan);

  /**
   * Make instances transient, removing them from management by this <code>PersistenceManager</code>
   * . If the useFetchPlan parameter is false, this method behaves exactly as
   * makeTransientAll(Object[] pcs).
   *
   * <p>The affected instance(s) lose their JDO identity and are no longer associated with any
   * <code>PersistenceManager</code>. The state of fields is unchanged.
   *
   * <p>If the useFetchPlan parameter is true, then the current FetchPlan is applied to the pcs
   * parameters and the entire graph of instances reachable via loaded fields is made transient. The
   * state of fields in the affected instances is as specified by the FetchPlan.
   *
   * <p>Unlike detachCopy, the instances are not detached; there is no detachment information in the
   * instances.
   *
   * <p>The instances to be made transient do not need to implement the javax.jdo.spi.Detachable
   * interface.
   *
   * @param pcs the root instances to make transient.
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to make transient
   * @since 2.1
   */
  void makeTransientAll(boolean useFetchPlan, Object... pcs);

  /**
   * Make instances transient, removing them from management by this <code>PersistenceManager</code>
   * . If the useFetchPlan parameter is false, this method behaves exactly as
   * makeTransientAll(Collection pcs).
   *
   * <p>The affected instance(s) lose their JDO identity and are no longer associated with any
   * <code>PersistenceManager</code>. The state of fields is unchanged.
   *
   * <p>If the useFetchPlan parameter is true, then the current FetchPlan is applied to the pcs
   * parameters and the entire graph of instances reachable via loaded fields is made transient. The
   * state of fields in the affected instances is as specified by the FetchPlan.
   *
   * <p>Unlike detachCopy, the instances are not detached; there is no detachment information in the
   * instances.
   *
   * <p>The instances to be made transient do not need to implement the javax.jdo.spi.Detachable
   * interface.
   *
   * @param pcs the root instances to make transient.
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to make transient
   * @since 2.0
   */
  void makeTransientAll(Collection<?> pcs, boolean useFetchPlan);

  /**
   * Make an instance subject to transactional boundaries.
   *
   * <p>Transient instances normally do not observe transaction boundaries. This method makes
   * transient instances sensitive to transaction completion. If an instance is modified in a
   * transaction, and the transaction rolls back, the state of the instance is restored to the state
   * before the first change in the transaction.
   *
   * <p>For persistent instances read in optimistic transactions, this method allows the application
   * to make the state of the instance part of the transactional state. At transaction commit, the
   * state of the instance in the cache is compared to the state of the instance in the data store.
   * If they are not the same, then an exception is thrown.
   *
   * @param pc the instance to make transactional.
   */
  void makeTransactional(Object pc);

  /**
   * Make an array of instances subject to transactional boundaries.
   *
   * @param pcs the array of instances to make transactional.
   * @see #makeTransactional(Object pc)
   */
  void makeTransactionalAll(Object... pcs);

  /**
   * Make a <code>Collection</code> of instances subject to transactional boundaries.
   *
   * @param pcs the <code>Collection</code> of instances to make transactional.
   * @see #makeTransactional(Object pc)
   */
  void makeTransactionalAll(Collection<?> pcs);

  /**
   * Make an instance non-transactional after commit.
   *
   * <p>Normally, at transaction completion, instances are evicted from the cache. This method
   * allows an application to identify an instance as not being evicted from the cache at
   * transaction completion. Instead, the instance remains in the cache with nontransactional state.
   *
   * @param pc the instance to make nontransactional.
   */
  void makeNontransactional(Object pc);

  /**
   * Make an array of instances non-transactional after commit.
   *
   * @param pcs the array of instances to make nontransactional.
   * @see #makeNontransactional(Object pc)
   */
  void makeNontransactionalAll(Object... pcs);

  /**
   * Make a <code>Collection</code> of instances non-transactional after commit.
   *
   * @param pcs the <code>Collection</code> of instances to make nontransactional.
   * @see #makeNontransactional(Object pc)
   */
  void makeNontransactionalAll(Collection<?> pcs);

  /**
   * Retrieve field values of an instance from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instance, and its field values must be
   * retrieved.
   *
   * <p>The <code>PersistenceManager</code> might use policy information about the class to retrieve
   * associated instances.
   *
   * @param pc the instance
   */
  void retrieve(Object pc);

  /**
   * Retrieve field values of an instance from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instance, and its field values must be
   * retrieved.
   *
   * <p>If the useFetchPlan parameter is false, this method behaves exactly as the corresponding
   * method without the useFetchPlan parameter. If the useFetchPlan parameter is true, and the fetch
   * plan has not been modified from its default setting, all fields in the current fetch plan are
   * fetched, and other fields might be fetched lazily by the implementation. If the useFetchPlan
   * parameter is true, and the fetch plan has been changed from its default setting, then the
   * fields specified by the fetch plan are loaded, along with related instances specified by the
   * fetch plan.
   *
   * @param pc the instance
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to retrieve.
   * @since 2.0
   */
  void retrieve(Object pc, boolean useFetchPlan);

  /**
   * Retrieve field values of instances from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instances, and all field values must be
   * retrieved.
   *
   * <p>The <code>PersistenceManager</code> might use policy information about the class to retrieve
   * associated instances.
   *
   * @param pcs the instances
   */
  void retrieveAll(Collection<?> pcs);

  /**
   * Retrieve field values of instances from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instances, and their field values should be
   * retrieved. The fields in the current fetch group must be retrieved, and the implementation
   * might retrieve more fields than the current fetch group.
   *
   * <p>If the useFetchPlan parameter is false, this method behaves exactly as the corresponding
   * method without the useFetchPlan parameter. If the useFetchPlan parameter is true, and the fetch
   * plan has not been modified from its default setting, all fields in the current fetch plan are
   * fetched, and other fields might be fetched lazily by the implementation. If the useFetchPlan
   * parameter is true, and the fetch plan has been changed from its default setting, then the
   * fields specified by the fetch plan are loaded, along with related instances specified by the
   * fetch plan.
   *
   * @param pcs the instances
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to retrieve.
   * @since 1.0.1
   */
  void retrieveAll(Collection<?> pcs, boolean useFetchPlan);

  /**
   * Retrieve field values of instances from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instances, and all field values must be
   * retrieved.
   *
   * <p>The <code>PersistenceManager</code> might use policy information about the class to retrieve
   * associated instances.
   *
   * @param pcs the instances
   */
  void retrieveAll(Object... pcs);

  /**
   * Retrieve field values of instances from the store. This tells the <code>PersistenceManager
   * </code> that the application intends to use the instances, and their field values should be
   * retrieved. The fields in the current fetch group must be retrieved, and the implementation
   * might retrieve more fields than the current fetch group.
   *
   * <p>If the useFetchPlan parameter is false, this method behaves exactly as the corresponding
   * method without the useFetchPlan parameter. If the useFetchPlan parameter is true, and the fetch
   * plan has not been modified from its default setting, all fields in the current fetch plan are
   * fetched, and other fields might be fetched lazily by the implementation. If the useFetchPlan
   * parameter is true, and the fetch plan has been changed from its default setting, then the
   * fields specified by the fetch plan are loaded, along with related instances specified by the
   * fetch plan.
   *
   * @param pcs the instances
   * @param useFetchPlan whether to use the current fetch plan to determine which fields to load and
   *     which instances to retrieve.
   * @since 2.1
   */
  void retrieveAll(boolean useFetchPlan, Object... pcs);

  /**
   * The application can manage the <code>PersistenceManager</code> instances more easily by having
   * an application object associated with each <code>PersistenceManager</code> instance.
   *
   * @param o the user instance to be remembered by the <code>PersistenceManager</code>
   * @see #getUserObject
   */
  void setUserObject(Object o);

  /**
   * The application can manage the <code>PersistenceManager</code> instances more easily by having
   * an application object associated with each <code>PersistenceManager</code> instance.
   *
   * @return the user object associated with this <code>PersistenceManager</code>
   * @see #setUserObject
   */
  Object getUserObject();

  /**
   * This method returns the <code>PersistenceManagerFactory</code> used to create this <code>
   * PersistenceManager</code>.
   *
   * @return the <code>PersistenceManagerFactory</code> that created this <code>PersistenceManager
   *     </code>
   */
  PersistenceManagerFactory getPersistenceManagerFactory();

  /**
   * Return the <code>Class</code> that implements the JDO Identity for the specified <code>
   * PersistenceCapable</code> class. The application can use the returned <code>Class</code> to
   * construct a JDO Identity instance for application identity <code>PersistenceCapable</code>
   * classes. This JDO Identity instance can then be used to get an instance of the <code>
   * PersistenceCapable</code> class for use in the application.
   *
   * <p>In order for the application to construct an instance of the ObjectId class it needs to know
   * the class being used by the JDO implementation.
   *
   * @param cls the <code>PersistenceCapable Class</code>
   * @return the <code>Class</code> of the ObjectId of the parameter
   * @see #getObjectById
   */
  Class<?> getObjectIdClass(Class<?> cls);

  /**
   * Set the Multithreaded flag for this <code>PersistenceManager</code>. Applications that use
   * multiple threads to invoke methods or access fields from instances managed by this <code>
   * PersistenceManager</code> must set this flag to <code>true</code>. Instances managed by this
   * <code>PersistenceManager</code> include persistent or transactional instances of <code>
   * PersistenceCapable</code> classes, as well as helper instances such as <code>Query</code>,
   * <code>Transaction</code>, or <code>Extent</code>.
   *
   * @param flag the Multithreaded setting.
   */
  void setMultithreaded(boolean flag);

  /**
   * Get the current Multithreaded flag for this <code>PersistenceManager</code>.
   *
   * @see #setMultithreaded
   * @return the Multithreaded setting.
   */
  boolean getMultithreaded();

  /**
   * Set the ignoreCache parameter for queries.
   *
   * <p>IgnoreCache set to <code>true</code> specifies that for all <code>Query</code> instances
   * created by this <code>PersistenceManager</code>, the default is the cache should be ignored for
   * queries.
   *
   * @param flag the ignoreCache setting.
   */
  void setIgnoreCache(boolean flag);

  /**
   * Get the ignoreCache setting for queries.
   *
   * <p>IgnoreCache set to <code>true</code> specifies that for all <code>Query</code> instances
   * created by this <code>PersistenceManager</code>, the default is the cache should be ignored for
   * queries.
   *
   * @return the ignoreCache setting.
   */
  boolean getIgnoreCache();

  /**
   * Specify a timeout interval (milliseconds) for any datastore read operations associated with
   * this persistence manager. To unset the explicit timeout, specify null. For no timeout, specify
   * 0. Read operations include, for example, those associated with query, getObjectById, refresh,
   * retrieve, and extent iteration operations. If the datastore granularity is larger than
   * milliseconds, the timeout value will be rounded up to the nearest supported datastore value. If
   * a read operation hasn't completed within this interval, the operation will throw a
   * JDODatastoreException. If multiple datastore operations are required to complete the query, the
   * timeout value applies to each of them individually. If the datastore and JDO implementation
   * support timeouts, then javax.jdo.option.DatastoreTimeout is returned by
   * PersistenceManagerFactory.supportedOptions(). If timeouts are not supported,this method will
   * throw JDOUnsupportedOptionException.
   *
   * @since 3.0
   * @param interval the timeout interval (milliseconds)
   */
  void setDatastoreReadTimeoutMillis(Integer interval);

  /**
   * Get the effective timeout setting for datastore read operations associated with this
   * persistence manager. If the timeout has not been set on this persistence manager explicitly,
   * the default read timeout value from the persistence manager factory is returned.
   *
   * @see #setDatastoreReadTimeoutMillis(Integer)
   * @see PersistenceManagerFactory#setDatastoreReadTimeoutMillis(Integer)
   * @return the effective timeout setting (milliseconds).
   * @since 3.0
   */
  Integer getDatastoreReadTimeoutMillis();

  /**
   * Specify a timeout interval (milliseconds) for any write operations associated with this
   * persistence manager. To unset the explicit timeout, specify null. For no timeout, specify 0.
   * Datastore write operations include, for example, operations associated with flush, commit, and
   * delete by query. If the datastore granularity is larger than milliseconds, the timeout value
   * will be rounded up to the nearest supported datastore value. If a write operation hasn't
   * completed within this interval, methods will throw a JDODatastoreException. If multiple
   * datastore operations are required to complete the method, the timeout value applies to each of
   * them individually. If the datastore and JDO implementation support timeouts, then
   * javax.jdo.option.DatastoreTimeout is returned by PersistenceManagerFactory.supportedOptions().
   * If timeouts are not supported,this method will throw JDOUnsupportedOptionException.
   *
   * @since 3.0
   * @param interval the timeout interval (milliseconds)
   */
  void setDatastoreWriteTimeoutMillis(Integer interval);

  /**
   * Get the effective timeout setting for write operations. If the timeout has not been set on this
   * persistence manager explicitly, the default datastore write timeout value from the persistence
   * manager factory is returned.
   *
   * @see #setDatastoreWriteTimeoutMillis(Integer)
   * @see PersistenceManagerFactory#setDatastoreWriteTimeoutMillis(Integer)
   * @return the effective timeout setting (milliseconds).
   * @since 3.0
   */
  Integer getDatastoreWriteTimeoutMillis();

  /**
   * Gets the detachAllOnCommit setting.
   *
   * @see #setDetachAllOnCommit(boolean)
   * @since 2.0
   * @return the detachAllOnCommit setting.
   */
  boolean getDetachAllOnCommit();

  /**
   * Sets the detachAllOnCommit setting.
   *
   * <p>DetachAllOnCommit set to <code>false</code> specifies that the state of persistent instances
   * in the cache after commit is defined by the <code>retainValues</code> flag. With this flag set
   * to true, during beforeCompletion all cached instances are prepared for detachment according to
   * the fetch plan in effect at commit. Loading fields and unloading fields required by the fetch
   * plan is done after calling the user's <code>beforeCompletion</code> callback. During <code>
   * afterCompletion</code>, before calling the user's <code>afterCompletion</code> callback, all
   * detachable persistent instances in the cache transition to detached; non-detachable persistent
   * instances transition to transient; and detachable instances can be serialized as detached
   * instances. Transient transactional instances are unaffected by this flag.
   *
   * @param flag Flag for whether to detach all on commit
   * @see #getDetachAllOnCommit()
   * @since 2.0
   */
  void setDetachAllOnCommit(boolean flag);

  /**
   * Gets the copyOnAttach setting.
   *
   * @see #setCopyOnAttach(boolean)
   * @since 2.1
   * @return the copyOnAttach setting.
   */
  boolean getCopyOnAttach();

  /**
   * Sets the copyOnAttach setting.
   *
   * <p>CopyOnAttach set to <code>true</code> specifies that during makePersistent, copies are made
   * of detached parameter instances. With this flag set to <code>false</code>, detached parameter
   * instances are attached directly and change their state from detached-clean to persistent-clean
   * or from detached-dirty to persistent-dirty.
   *
   * @param flag Flag for whether to copy on attach
   * @see #getCopyOnAttach()
   * @since 2.1
   */
  void setCopyOnAttach(boolean flag);

  /**
   * Detach the specified instance from the <code>PersistenceManager</code>. The flags for
   * detachment (DETACH_LOAD_FIELDS and DETACH_UNLOAD_FIELDS) and the active fetch groups determine
   * the scope of fetching for the graph of instances reachable from the pc parameter. The state of
   * fields in the affected instances is as specified by the FetchPlan.
   *
   * @param pc the instance to detach
   * @return the detached instance
   * @see #detachCopyAll(Object[])
   * @since 2.0
   * @param <T> Type of the persistable object
   */
  <T> T detachCopy(T pc);

  /**
   * Detach the specified instances from the <code>PersistenceManager</code>. The flags for
   * detachment (DETACH_LOAD_FIELDS and DETACH_UNLOAD_FIELDS) and the active fetch groups determine
   * the scope of fetching for the graph of instances reachable from the pcs parameter. The state of
   * fields in the affected instances is as specified by the FetchPlan.
   *
   * @param pcs the instances to detach
   * @return the detached instances
   * @see #detachCopyAll(Object[])
   * @since 2.0
   * @param <T> Type of the persistable objects
   */
  <T> Collection<T> detachCopyAll(Collection<T> pcs);

  /**
   * Detach the specified instances from the <code>PersistenceManager</code>. The flags for
   * detachment (DETACH_LOAD_FIELDS and DETACH_UNLOAD_FIELDS) and the active fetch groups determine
   * the scope of fetching for the graph of instances reachable from the pcs parameter. The state of
   * fields in the affected instances is as specified by the FetchPlan. The objects returned can be
   * manipulated and re-attached with {@link #makePersistentAll(Object[])}. The detached instances
   * will be unmanaged copies of the specified parameters, and are suitable for serialization and
   * manipulation outside of a JDO environment. When detaching instances, only fields in the current
   * {@link FetchPlan} will be traversed. Thus, to detach a graph of objects, relations to other
   * persistent instances must either be in the <code>default-fetch-group</code>, or in the current
   * custom {@link FetchPlan}.
   *
   * @param pcs the instances to detach
   * @return the detached instances
   * @throws JDOUserException if any of the instances to be detached do not implement the
   *     javax.jdo.spi.Detachable interface.
   * @see #makePersistentAll(Object[])
   * @see #getFetchPlan
   * @since 2.0
   * @param <T> Type of the persistable object
   */
  @SuppressWarnings({"unchecked", "varargs"})
  <T> T[] detachCopyAll(T... pcs);

  /**
   * Put the specified key-value pair into the map of user objects.
   *
   * @since 2.0
   * @param key Key to store the user object under
   * @param val User object to store
   * @return The previous object under this key
   */
  Object putUserObject(Object key, Object val);

  /**
   * Get the value for the specified key from the map of user objects.
   *
   * @param key the key of the object to be returned
   * @return the object
   * @since 2.0
   */
  Object getUserObject(Object key);

  /**
   * Remove the specified key and its value from the map of user objects.
   *
   * @param key the key of the object to be removed
   * @return The user object that was removed
   * @since 2.0
   */
  Object removeUserObject(Object key);

  /**
   * Flushes all dirty, new, and deleted instances to the data store. It has no effect if a
   * transaction is not active.
   *
   * <p>If a datastore transaction is active, this method synchronizes the cache with the datastore
   * and reports any exceptions.
   *
   * <p>If an optimistic transaction is active, this method obtains a datastore connection,
   * synchronizes the cache with the datastore using this connection and reports any exceptions. The
   * connection obtained by this method is held until the end of the transaction.
   *
   * <p>If exceptions occur during flush, the implementation will set the current transaction's
   * <code>RollbackOnly</code> flag (see {@link Transaction#setRollbackOnly}).
   *
   * @since 2.0
   */
  void flush();

  /**
   * Validates the <code>PersistenceManager</code> cache with the datastore. This method has no
   * effect if a transaction is not active.
   *
   * <p>If a datastore transaction is active, this method verifies the consistency of instances in
   * the cache against the datastore. An implementation might flush instances as if {@link #flush}
   * were called, but it is not required to do so.
   *
   * <p>If an optimistic transaction is active, this method obtains a datastore connection and
   * verifies the consistency of the instances in the cache against the datastore. If any
   * inconsistencies are detected, a {@link JDOOptimisticVerificationException} is thrown. This
   * exception contains a nested {@link JDOOptimisticVerificationException} for each object that
   * failed the consistency check. No datastore resources acquired during the execution of this
   * method are held beyond the scope of this method.
   *
   * @since 2.0
   */
  void checkConsistency();

  /**
   * Returns the <code>FetchPlan</code> used by this <code>PersistenceManager</code>.
   *
   * @return the FetchPlan
   * @since 2.0
   */
  FetchPlan getFetchPlan();

  /**
   * Creates an instance of a persistence-capable interface, or of a concrete or abstract class. The
   * returned instance is transient.
   *
   * @param pcClass Must be a persistence-capable interface, or a concrete or abstract class that is
   *     declared in the metadata.
   * @return the created instance
   * @since 2.0
   * @param <T> Type of the persistable object
   */
  <T> T newInstance(Class<T> pcClass);

  /**
   * Returns the sequence identified by <code>name</code>.
   *
   * @param name the name of the Sequence
   * @return the Sequence
   * @since 2.0
   */
  Sequence getSequence(String name);

  /**
   * If this method is called while a datastore transaction is active, the object returned will be
   * enlisted in the current transaction. If called in an optimistic transaction or outside an
   * active transaction, the object returned will not be enlisted in any transaction.
   *
   * @return the JDOConnection instance
   * @since 2.0
   */
  JDOConnection getDataStoreConnection();

  /**
   * Adds the listener instance to the list of lifecycle event listeners. The <code>classes</code>
   * parameter identifies all of the classes of interest. If the <code>classes</code> parameter is
   * specified as <code>null</code>, events for all persistent classes and interfaces will be sent
   * to <code>listenerInstance</code>.
   *
   * <p>The listenerInstance will be called for each event for which it implements the corresponding
   * listenerInstance interface.
   *
   * @param listener the lifecycle listener
   * @param classes the classes of interest to the listener
   * @since 2.0
   */
  void addInstanceLifecycleListener(InstanceLifecycleListener listener, Class<?>... classes);

  /**
   * Removes the listener instance from the list of lifecycle event listeners.
   *
   * @param listener the listener instance to be removed
   * @since 2.0
   */
  void removeInstanceLifecycleListener(InstanceLifecycleListener listener);

  /**
   * Get the Date as seen by the server. Clients using this method can order their operations
   * according to a single time source. Implementations use the setting of the server time zone to
   * prepare a Date instance that represents UTC time on the server.
   *
   * @return a Date instance corresponding to the UTC Date as seen by the server
   * @since 2.1
   */
  Date getServerDate();

  /**
   * Get the objects managed by this persistence manager.
   *
   * @return the objects
   * @since 2.1
   */
  Set getManagedObjects();

  /**
   * Get the objects managed by this persistence manager having the specified object states.
   *
   * @param states The states of objects that we are interested in
   * @return the objects
   * @since 2.1
   */
  Set getManagedObjects(EnumSet<ObjectState> states);

  /**
   * Get the objects managed by this persistence manager being instances of the specified classes.
   *
   * @param classes The classes of objects that we are interested in
   * @return the objects
   * @since 2.1
   */
  Set getManagedObjects(Class<?>... classes);

  /**
   * Get the objects managed by this persistence manager having the specified object states and
   * being instances of the specified classes.
   *
   * @param states The states of objects that we are interested in
   * @param classes The classes of objects that we are interested in
   * @return the objects
   * @since 2.1
   */
  Set getManagedObjects(EnumSet<ObjectState> states, Class<?>... classes);

  /**
   * Get a modifiable <code>FetchGroup</code> for the Class and name. If a modifiable <code>
   * FetchGroup</code> already exists in the <code>PersistenceManager</code> scope, return it. If
   * not, create and populate a new <code>FetchGroup</code> from the existing definition in the
   * {@link PersistenceManager} or {@link PersistenceManagerFactory}. If the definition for the
   * <code>FetchGroup</code> is not in scope in either the <code>PersistenceManager</code> or <code>
   * PersistenceManagerFactory</code>, create it with no members. The <code>FetchGroup</code>
   * immediately becomes active and in scope of the PersistenceManager, and hides the corresponding
   * fetch group in the PersistenceManagerFactory.
   *
   * @param cls the class or interface for the <code>FetchGroup</code>
   * @param name the name of the fetch group
   * @return the FetchGroup
   * @throws JDOUserException if the class is not a persistence-capable class or interface
   * @since 2.2
   */
  FetchGroup getFetchGroup(Class<?> cls, String name);

  /**
   * Set a persistence manager property. This can be a standard property or a vendor-extension
   * property. If a vendor-extension property is not recognized, it is silently ignored.
   *
   * @param propertyName name of property
   * @param value The value
   * @throws JDOUserException if the value is not supported for the property
   * @since 3.1
   */
  public void setProperty(String propertyName, Object value);

  /**
   * Get the properties and associated values currently in effect for the persistence manager.
   * Changing entries in the map will not have affect the configuration of the persistence manager.
   *
   * @return map of properties in effect
   * @since 3.1
   */
  public Map<String, Object> getProperties();

  /**
   * Get the names of the properties that are supported for use with the persistence manager. These
   * can be standard JDO properties, or can be vendor-extension properties.
   *
   * @return property names Names of the properties accepted
   * @since 3.1
   */
  public Set<String> getSupportedProperties();
}
