Basically, we mark all local serialization operations the same 
way you would mark a transaction.

LOCAL to LOCAL SERIALIZATION

Definition:
    This is a full serialization/deserialization takes place in 
    the local vm inside the marked scope of the IntraVM server.

Circumstances:
    When an IntraVM implementation of a javax.ejb.* interface is 
    serialized in the scope of a local IntraVM serialization.

    These serializations happen when objects are passed as 
    parameters or return values from one client/ejb to another 
    client/ejb running inside the same VM.

Action: 
    Temporarily cache the instance in memory during 
    serialization, retrieve again during deserialization.

Example Scenario:
    BEFORE SERIALIZATION
    1.  Call IntraVmCopyMonitor.preCopyOperation().
    2.  Method parameters are sent to ObjectOutputStream.
    SERIALIZATION
    3.  ObjectOutputStream encounters an IntraVmMetaData instance 
        in the object graph and calls its writeReplace method.
    4.  The IntraVmMetaData instance determines it is being 
        serialized in the scope of an IntraVM serialization by 
        calling IntraVmCopyMonitor.isIntraVmCopyOperation().
    5.  The IntraVmMetaData instance creates an IntraVmArtifact 
        that caches it in a static hashtable keyed on a 
        combination of the thread id and instance hashCode.
    6.  The IntraVmMetaData instance returns the IntraVmArtifact 
        instance from the writeReplace method.
    7.  The ObjectOutputStream serializes the IntraVmArtifact 
        instance in place of the IntraVmMetaData instance.
    DESERIALIZATION
    8.  ObjectInputStream encounters and deserializes an 
        IntraVmArtifact instance and calls its readResolve method.
    9.  The IntraVmArtifact instance uses the key it created in 
        step 5 to retrieve the IntraVmMetaData instance from the 
        static hashtable.
    10. The IntraVmArtifact instance returns the IntraVmMetaData 
        instance from the readResolve method.
    11. ObjectInputStream places the IntraVmMetaData instance in 
        the object graph in place of the IntraVmArtifact 
        instance.
    AFTER
    12. Method parameters are no de-referenced as mandated by the 
        spec and can be passed into the bean's method.
    13. IntraVmCopyMonitor.postCopyOperation() is called, ending 
        the local IntraVm serialization scope.
 
LOCAL to REMOTE SERIALIZATION 

Definition:
    This is a serialization that initiates in the local vm, but 
    is outside the scope of a marked IntraVM local serialization.
    
Circumstances:
    When an IntraVM implementation of a javax.ejb.* interface is 
    serialized outside the scope of the IntraVM Server
        
    These serializations happen when objects are sent from a 
    local bean to a remote client as part of a return value, or 
    when a stateful session bean is passified.

Action:
    Don't serialize the IntraVM javax.ejb.* interface 
    implementation, instead ask the ApplicationServer to nominate 
    its own implementation as a replacement.  This is done via 
    the org.openejb.spi.ApplicationServer interface.

Example Scenario:
    SERIALIZATION
    1.  ObjectOutputStream encounters an IntraVmMetaData instance 
        in the object graph and calls its writeReplace method.
    2.  The IntraVmMetaData instance determines it is being 
        serialized outside the scope of an IntraVM serialization
        by calling IntraVmCopyMonitor.isIntraVmCopyOperation().
    3.  The IntraVmMetaData instance calls the getEJBMetaData 
        method on the ApplicationServer.
    4.  The IntraVmMetaData instance returns the 
        ApplicationServer's EJBMetaData instance from the 
        writeReplace method.
    5.  The ObjectOutputStream serializes the ApplicationServer's 
        EJBMetaData instance in place of the IntraVmMetaData 
        instance.  
        
        Note:  The ApplicationServer's EJBMetaData instance can 
        be any object that implements the javax.ejb.EJBMetaData 
        interface and can also implement any serialization 
        methods, such as the writeReplace method, to nominate a 
        replacement or implement protocol specific logic or 
        otherwise gain control over the serialization of 
        EJBMetaData instances destined for its remote clients.  
        
    DESERIALIZATION
        The deserialization of the Application Server's 
        javax.ejb.* implementations is implementation specific.

REMOTE to LOCAL SERIALIZATION 

Definition:
    This is a full serialization/deserialization takes place in 
    the local vm inside the marked scope of the IntraVM server.

Circumstances:
    When an IntraVM implementation of a javax.ejb.* interface is 
    serialized in the scope of a local IntraVM serialization.

    These serializations happen when objects are passed as 
    parameters or return values from one client/ejb to another 
    client/ejb running inside the same VM.





REMOTE to LOCAL SERIALIZATION  

Definition:
    This is a serialization that initiates in a remote client vm 
    and finishes in same vm as the Application Server.
    
Circumstances:
    When an ApplicationServer-specific implementation of a 
    javax.ejb.* interface is serialized outside the scope of the 
    client vm and deserializes in the Application Server and 
    OpenEJB IntraVM Server's vm.
        
    These serializations happen, for example, when javax.ejb.* 
    objects are used as parameters to an EJBObject method either 
    directly or nested in another object.

Action:
    No special action is required by the OpenEJB specification.

Notes on Optimization:    
    For optimization purposes, the ApplicationServer can replace 
    its javax.ejb.* interface implementations with those created 
    by the IntraVM Server.

    The Application Server may wish to this by implementing the 
    serialization readResolve method in it's javax.ejb.* 
    implementations.  Then, when these implementations are 
    deserialized, certain checks can be made to determine if they 
    in the same VM as the Application Server and OpenEJB IntraVM 
    Server. If they are, it can replace itself with the 
    equivalent IntraVM Server implementation.  An easy way for an 
    implementation to determine which VM it is in is to simply 
    set a system variable that is only present in the Application 
    Server's VM.
    
    This is identical to how the IntraVM Server replaces its 
    javax.ejb.* interface implementations with those created by 
    the ApplicationServer when objects are leaving the local VM.  
    
