--- /dev/null
+This documents the life cycle of message as it arrives and is handled by
+a basic async, packetized NAL. There are four types of messages that have
+slightly different life cycles, so they are addressed independently.
+
+
+Put request
+-----------
+
+1. NAL notices that there is a incoming message header on the network
+and reads an ptl_hdr_t in from the wire.
+
+2. It may store additional NAL specific data that provides context
+for this event in a void* that it will interpret in some fashion
+later.
+
+3. The NAL calls lib_parse() with a pointer to the header and its
+private data structure.
+
+4. The library decodes the header and may build a message state
+object that describes the event to be written and the ACK to be
+sent, if any. It then calls nal->recv() with the private data
+that the NAL passed in, a pointer to the message state object
+and a translated user address.
+
+ The NAL will have been given a chance to pretranslate
+ all user addresses when the buffers are created. This
+ process is described in the NAL-HOWTO.
+
+5. The NAL should restore what ever context it required from the
+private data pointer, begin receiving the bytes and possibly store
+some extra state of its own. It should return at this point.
+
+
+
+Get request
+-----------
+
+1. As with a Put, the NAL notices the incoming message header and
+passes it to lib_parse().
+
+2. The library decodes the header and calls nal->recv() with a
+zero byte length, offset and destination to instruct it to clean
+up the wire after reading the header. The private data will
+be passed in as well, allowing the NAL to retrieve any state
+or context that it requires.
+
+3. The library may build a message state object to possibly
+write an event log or invalidate a memory region.
+
+4. The library will build a ptl_msg_t header that specifies the
+Portals protocol information for delivery at the remote end.
+
+5. The library calls nal->send() with the pre-built header,
+the optional message state object, the four part address
+component, a translated user pointer + offset, and some
+other things.
+
+6. The NAL is to put the header on the wire or copy it at
+this point (since it off the stack). It should store some
+amount of state about its current position in the message and
+the destination address.
+
+7. And then return to the library.
+
+
+Reply request
+-------------
+
+1. Starting at "The library decodes the header..."
+
+2. The library decodes the header and calls nal->recv()
+to bring in the rest of the message. Flow continues in
+exactly the same fashion as with all other receives.
+
+
+Ack request
+-----------
+
+1. The library decodes the header, builds the appropriate data
+structures for the event in a message state object and calls nal->recv()
+with a zero byte length, etc.
+
+
+Packet arrival
+--------------
+
+1. The NAL should notice the arrival of a packet, retrieve whatever
+state it needs from the message ID or other NAL specific header data
+and place the data bytes directly into the user address that were
+given to nal->recv().
+
+ How this happens is outside the scope of the Portals library
+ and soley determined by the NAL...
+
+2. If this is the last packet in a message, the NAL should retrieve
+the lib_msg_t *cookie that it was given in the call to nal->recv()
+and pass it to lib_finalize(). lib_finalize() may call nal->send()
+to send an ACK, nal->write() to record an entry in the event log,
+nal->invalidate() to unregister a region of memory or do nothing at all.
+
+3. It should then clean up any remaining NAL specific state about
+the message and go back into the main loop.
+
+
+Outgoing packets
+----------------
+
+1. When the NAL has pending output, it should put the packets on
+the wire wrapped with whatever implementation specified wrappers.
+
+2. Once it has output all the packets of a message it should
+call lib_finalize() with the message state object that was
+handed to nal->send(). This will allows the library to clean
+up its state regarding the message and write any pending event
+entries.
+
+
+