{\em Delegation} is a means by which a library writer can 
intercept messages sent via a proxy.  This is typically
used to construct communication libraries.
A library creates a special kind of Group called a 
\kw{DelegationManager}, which receives the messages
sent via a delegated proxy.

There are two parts to the delegation interface-- a
very small client-side interface to enable delegation,
and a more complex manager-side interface to handle
the resulting redirected messages.

\section{Client Interface}

All proxies (Chare, Group, Array, ...) in \charmpp\ 
support the following delegation routines.

\function{void CProxy::ckDelegate(CkGroupID delMgr);}
Begin delegating messages sent via this proxy to the
given delegation manager. This only affects
the proxy it is called on-- other proxies for the
same object are {\em not} changed. If the proxy is 
already delegated, this call changes the delegation manager.

\function{CkGroupID CProxy::ckDelegatedIdx(void) const;}
Get this proxy's current delegation manager.

\function{void CProxy::ckUndelegate(void);}
Stop delegating messages sent via this proxy.  
This restores the proxy to normal operation.

One use of these routines might be:

\begin{alltt}
  CkGroupID mgr=somebodyElsesCommLib(...);
  CProxy_foo p=...;
  p.someEntry1(...); //Sent to foo normally
  p.ckDelegate(mgr);
  p.someEntry2(...); //Handled by mgr, not foo!
  p.someEntry3(...); //Handled by mgr again
  p.ckUndelegate();
  p.someEntry4(...); //Back to foo
\end{alltt}

The client interface is very simple; but it is often
not called by users directly.  Often the delegate 
manager library needs some other initialization,
so a more typical use would be:

\begin{alltt}
  CProxy_foo p=...;
  p.someEntry1(...); //Sent to foo normally
  startCommLib(p,...); // Calls ckDelegate on proxy
  p.someEntry2(...); //Handled by library, not foo!
  p.someEntry3(...); //Handled by library again
  finishCommLib(p,...); // Calls ckUndelegate on proxy
  p.someEntry4(...); //Back to foo
\end{alltt}

Sync entry methods, group and nodegroup multicast messages,
and messages for virtual chares that have not yet been created
are never delegated.  Instead, these kinds of entry methods
execute as usual, even if the proxy is delegated.

\section{Manager Interface}

A delegation manager is a group which inherits from
\kw{CkDelegateMgr} and overrides certain virtual methods. 
Since \kw{CkDelegateMgr} does not do any communication itself, 
it need not be mentioned in the
.ci file; you can simply declare a group as usual and
inherit the C++ implementation from \kw{CkDelegateMgr}.

Your delegation manager will be called by \charmpp{}
any time a proxy delegated to it is used.  Since
any kind of proxy can be delegated, there are separate
virtual methods for delegated Chares, Groups, NodeGroups,
and Arrays.

\begin{alltt}
class CkDelegateMgr : public Group {
public:
  virtual void ChareSend(int ep,void *m,const CkChareID *c,int onPE);

  virtual void GroupSend(int ep,void *m,int onPE,CkGroupID g);
  virtual void GroupBroadcast(int ep,void *m,CkGroupID g);

  virtual void NodeGroupSend(int ep,void *m,int onNode,CkNodeGroupID g);
  virtual void NodeGroupBroadcast(int ep,void *m,CkNodeGroupID g);

  virtual void ArrayCreate(int ep,void *m,const CkArrayIndex &idx,int onPE,CkArrayID a);
  virtual void ArraySend(int ep,void *m,const CkArrayIndex &idx,CkArrayID a);
  virtual void ArrayBroadcast(int ep,void *m,CkArrayID a);
  virtual void ArraySectionSend(int ep,void *m,CkArrayID a,CkSectionID &s);
};
\end{alltt}

These routines are called on the send side only.  They are called after 
parameter marshalling; but before the messages are packed.
The parameters passed in have the following descriptions.

\begin{enumerate}
\item{{\bf ep} The entry point begin called, passed as an index into the
\charmpp{} entry table.  This information is also stored in the message's
header; it is duplicated here for convenience.}
\item{{\bf m} The \charmpp{} message.  This is a pointer to the start of the
user data; use the system routine \kw{UsrToEnv} to get the corresponding envelope.
The messages are not necessarily packed; be sure to use \kw{CkPackMessage}.}
\item{{\bf c} The destination \kw{CkChareID}.  This information is already
stored in the message header.}
\item{{\bf onPE} The destination processor number. For chare messages, this
indicates the processor the chare lives on.  For group messages, this indicates
the destination processor.  For array create messages, this indicates the 
desired processor.}
\item{{\bf g} The destination \kw{CkGroupID}.  This is also stored in the 
message header.}
\item{{\bf onNode} The destination node.}
\item{{\bf idx} The destination array index.  This may be looked up using
the lastKnown method of the array manager, e.g., using:
  \begin{alltt}
  int lastPE=CProxy_CkArray(a).ckLocalBranch()->lastKnown(idx);
  \end{alltt} }
\item{{\bf s} The destination array section.}
\end{enumerate}


The \kw{CkDelegateMgr} superclass implements all these methods; so
you only need to implement those you wish to optimize.  You can
also call the superclass to do the final delivery after you've
sent your messages.



