-- Copyright (C) 1986 by Xerox Corporation.  All rights reserved.
-- Stub file  was translated on June 2, 1986 8:29:10 am PDT by Lupine of February 22, 1986 5:15:54 pm PST
-- Source interface ThParty came from file ThParty.bcd, which was created on June 2, 1986 8:28:52 am PDT with version stamp 112#234#6230400436 from source of June 2, 1986 8:28:42 am PDT.

-- The RPC stub modules for ThParty are:
--   ThPartyRpcControl.mesa;
--   ThPartyRpcClientImpl.mesa;
--   ThPartyRpcBinderImpl.mesa;
--   ThPartyRpcServerImpl.mesa.

-- The parameters for this translation are:
--   Target language = Cedar
--   Default parameter passing = VALUE
--   Deallocate server heap arguments = TRUE
--   Inline RpcServerImpl dispatcher stubs = TRUE
--   Declare signals = TRUE
--   Warn about short POINTER ("MDS") allocations = TRUE
--   Maximum number of dynamic heap NEWs = 50, MDS NEWs = 50
--   Acceptable parameter protocols = VersionRange[1..1].


DIRECTORY
  BasicTime,
  IV,
  RefID,
  RPC,
  Thrush,
  ThSmartsRpcControl,
  ThParty,
  ThPartyRpcControl USING [InterMdsCallsOnly, LupineProtocolVersion,
      ProcedureIndex, SignalIndex],
  RPCLupine --USING SOME OF [Call, DataLength, Dispatcher, ExportHandle,
      -- ExportInterface, GetStubPkt, maxDataLength, maxPrincipalLength,
      -- maxShortStringLength, pktOverhead, ReceiveExtraPkt, SendPrelimPkt,
      -- StartCall, StartSignal, StubPkt, UnexportInterface]--,
  LupineRuntime --USING SOME OF [BindingError, CheckPktLength, CopyFromPkt,
      -- CopyFromMultiplePkts, CopyToPkt, CopyToMultiplePkts, defaultZones,
      -- DispatchingError, FinishThisPkt, ListHeader, MarshalingError,
      -- MarshalingExprError, MarshalAtom, MarshalRope, NilHeader, ProtocolError,
      -- RopeHeader, RpcPktDoubleWord, RuntimeError, SequenceHeader, SHORT,
      -- StartNextPkt, StringHeader, StubPktDoubleWord, TranslationError,
      -- UnmarshalingError, UnmarshalingExprError, UnmarshalAtom, UnmarshalRope,
      -- WordsForChars]--,
  Atom --USING SOME OF [GetPName, MakeAtom]--,
  Rope --USING SOME OF [InlineFlatten, Length, NewText, Text]--;


ThPartyRpcServerImpl: MONITOR
  IMPORTS ThParty, RpcPrivate: RPCLupine, Lupine: LupineRuntime, Atom,
      Rope
  EXPORTS ThPartyRpcControl
  SHARES  ThParty, ThPartyRpcControl, Rope
  = BEGIN OPEN ThParty, RpcControl: ThPartyRpcControl, RpcPublic: RPC;


-- Standard remote binding routines.

  bound: BOOLEAN ← FALSE;
  myInterface: RpcPrivate.ExportHandle;
  paramZones: RpcPublic.Zones ← RpcPublic.standardZones;

  ExportInterface: PUBLIC ENTRY SAFE PROCEDURE [
        interfaceName: RpcPublic.InterfaceName,
        user: RpcPublic.Principal,
        password: RpcPublic.EncryptionKey,
        parameterStorage: RpcPublic.Zones ] =
    TRUSTED BEGIN ENABLE UNWIND => NULL;
    IsNull: PROCEDURE [string: Rope.ROPE] RETURNS [BOOLEAN] =
      INLINE {RETURN[string.Length[] = 0]};
    IF bound THEN Lupine.BindingError;
    myInterface ← RpcPrivate.ExportInterface [
      interface: [
        type: IF ~IsNull[interfaceName.type]
          THEN interfaceName.type ELSE "ThParty~112#234#6230400436",
        instance: interfaceName.instance,
        version: interfaceName.version ],
      user: user,  password: password,
      dispatcher: ServerDispatcher,
      localOnly: RpcControl.InterMdsCallsOnly,
      stubProtocol: RpcControl.LupineProtocolVersion ];
    paramZones ← [
      gc: IF parameterStorage.gc # NIL
        THEN parameterStorage.gc ELSE Lupine.defaultZones.gc,
      heap: IF parameterStorage.heap # NIL
        THEN parameterStorage.heap ELSE Lupine.defaultZones.heap,
      mds: IF parameterStorage.mds # NIL
        THEN parameterStorage.mds ELSE Lupine.defaultZones.mds ];
    bound ← TRUE;
    END;

  UnexportInterface: PUBLIC ENTRY SAFE PROCEDURE =
    TRUSTED BEGIN ENABLE UNWIND => NULL;
    IF ~bound THEN Lupine.BindingError;
    myInterface ← RpcPrivate.UnexportInterface[myInterface];
    paramZones ← RpcPublic.standardZones;
    bound ← FALSE;
    END;


-- Public procedure dispatcher and public signal and error catcher.

  ServerDispatcher: --PROCEDURE [pkt: RPCPkt, callLength: DataLength,
      -- lastPkt: BOOLEAN, localConversation: Conversation] RETURNS [returnLength:
      -- DataLength]-- RpcPrivate.Dispatcher =
    BEGIN

    -- Catch public signals.

      ENABLE BEGIN

      END;  -- Catch public signals.


    -- Call public procedures (still in dispatcher).

    SELECT LOOPHOLE[pkt.data[0], RpcControl.ProcedureIndex] FROM
      CreateConversation => RETURN[
        CreateConversationStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      Alert => RETURN[
        AlertStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Advance => RETURN[
        AdvanceStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      ReportAction => RETURN[
        ReportActionStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetConversationInfo => RETURN[
        GetConversationInfoStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetPartyInfo => RETURN[
        GetPartyInfoStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetKeyTable => RETURN[
        GetKeyTableStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      DescribeParty => RETURN[
        DescribePartyStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      RegisterServiceInterface => RETURN[
        RegisterServiceInterfaceStub[pkt: pkt, callLength: callLength,
            lastPkt: lastPkt, localConversation: localConversation]];
      LookupServiceInterface => RETURN[
        LookupServiceInterfaceStub[pkt: pkt, callLength: callLength,
            lastPkt: lastPkt, localConversation: localConversation]];
      RegisterKey => RETURN[
        RegisterKeyStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetParty => RETURN[
        GetPartyStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      GetPartyFromNumber => RETURN[
        GetPartyFromNumberStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetPartyFromFeepNum => RETURN[
        GetPartyFromFeepNumStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetCurrentParty => RETURN[
        GetCurrentPartyStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      GetNumbersForRName => RETURN[
        GetNumbersForRNameStub[pkt: pkt, callLength: callLength, lastPkt:
            lastPkt, localConversation: localConversation]];
      Register => RETURN[
        RegisterStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      CheckIn => RETURN[
        CheckInStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Deregister => RETURN[
        DeregisterStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Enable => RETURN[
        EnableStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      Disable => RETURN[
        DisableStub[pkt: pkt, callLength: callLength, lastPkt: lastPkt,
            localConversation: localConversation]];
      ENDCASE => RETURN[Lupine.DispatchingError[]];

    END;  -- ServerDispatcher


-- Public procedure dispatcher stubs.

  CreateConversationStub: --PROCEDURE [shhh: SHHH, credentials: Credentials,
      -- state: Thrush.StateInConv, urgency: Thrush.CallUrgency, alertKind:
      -- Thrush.AlertKind, reason: Thrush.Reason, comment: ROPE, subject:
      -- Thrush.ROPE]
    -- RETURNS [nb: NB, convEvent: Thrush.ConvEvent]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    credentials: Credentials;
    state: Thrush.StateInConv;
    urgency: Thrush.CallUrgency;
    alertKind: Thrush.AlertKind;
    reason: Thrush.Reason;
    comment: ROPE;
    subject: Thrush.ROPE;
    nb: NB;
    convEvent: Thrush.ConvEvent;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, state (9): Thrush.StateInConv];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 10;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [credentials: credentials, state: state] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal urgency: Thrush.CallUrgency from pkt.data[pktLength].
      [urgency, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal urgency.
    BEGIN  -- Unmarshal alertKind: Thrush.AlertKind from pkt.data[pktLength].
      [alertKind, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal alertKind.
    BEGIN  -- Unmarshal reason: Thrush.Reason from pkt.data[pktLength].
      [reason, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal reason.
    BEGIN  -- Unmarshal comment: ROPE from pkt.data[pktLength].
      [comment, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal comment.
    BEGIN  -- Unmarshal subject: Thrush.ROPE from pkt.data[pktLength].
      [subject, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal subject.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb, convEvent] ←
          CreateConversation[localConversation, argPkt.credentials,
              argPkt.state, urgency, alertKind, reason, comment, subject]
      ELSE [nb, convEvent] ←
          CreateConversation[localConversation, credentials, state,
              urgency, alertKind, reason, comment, subject];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal convEvent: Thrush.ConvEvent to pkt.data[pktLength].
      pktLength ← MarshalThrushDotConvEvent[convEvent, pkt, pktLength];
      END;  -- Marshal convEvent.
    RETURN[returnLength: pktLength];
    END;  -- CreateConversationStub.

  AlertStub: --PROCEDURE [shhh: SHHH, credentials: Credentials, calledPartyID:
      -- PartyID, comment: ROPE]
    -- RETURNS [nb: NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    credentials: Credentials;
    calledPartyID: PartyID;
    comment: ROPE;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, calledPartyID (9): PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 11;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [credentials: credentials, calledPartyID: calledPartyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal comment: ROPE from pkt.data[pktLength].
      [comment, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal comment.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb] ← Alert[localConversation, argPkt.credentials, argPkt.calledPartyID,
          comment]
      ELSE [nb] ← Alert[localConversation, credentials, calledPartyID,
          comment];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- AlertStub.

  AdvanceStub: --PROCEDURE [shhh: SHHH, credentials: Credentials, state:
      -- Thrush.StateInConv, reportToAll: BOOL, reason: Thrush.Reason,
      -- comment: ROPE]
    -- RETURNS [nb: NB, convEvent: Thrush.ConvEvent]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    credentials: Credentials;
    state: Thrush.StateInConv;
    reportToAll: BOOL;
    reason: Thrush.Reason;
    comment: ROPE;
    nb: NB;
    convEvent: Thrush.ConvEvent;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, state (9): Thrush.StateInConv, reportToAll (10): BOOL];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 11;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [credentials: credentials, state: state, reportToAll: reportToAll]
          ← argPkt↑;
      END;
    BEGIN  -- Unmarshal reason: Thrush.Reason from pkt.data[pktLength].
      [reason, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal reason.
    BEGIN  -- Unmarshal comment: ROPE from pkt.data[pktLength].
      [comment, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal comment.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb, convEvent] ←
          Advance[localConversation, argPkt.credentials, argPkt.state,
              argPkt.reportToAll, reason, comment]
      ELSE [nb, convEvent] ←
          Advance[localConversation, credentials, state, reportToAll,
              reason, comment];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal convEvent: Thrush.ConvEvent to pkt.data[pktLength].
      pktLength ← MarshalThrushDotConvEvent[convEvent, pkt, pktLength];
      END;  -- Marshal convEvent.
    RETURN[returnLength: pktLength];
    END;  -- AdvanceStub.

  ReportActionStub: --PROCEDURE [shhh: SHHH, report: Thrush.ActionReport,
      -- reportToAll: BOOL]
    -- RETURNS [nb: NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    report: Thrush.ActionReport;
    reportToAll: BOOL;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, reportToAll (1):
        BOOL];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 2;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [reportToAll: reportToAll] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal report: Thrush.ActionReport from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @report, dataLength: SIZE[Thrush.ActionReport], alwaysOnePkt:
          FALSE];
      -- Restore garbled REFs to NIL following copy.
      BEGIN OPEN record: report;
      LOOPHOLE[record.actionClass, LONG POINTER] ← NIL;
      LOOPHOLE[record.actionType, LONG POINTER] ← NIL;
      LOOPHOLE[record.actionInfo, LONG POINTER] ← NIL;
      END;  -- OPEN record: report.
      BEGIN OPEN record: report;
      BEGIN  -- Unmarshal record.actionClass: ActionClass from pkt.data[pktLength].
        [record.actionClass, pktLength] ← Lupine.UnmarshalAtom[pkt,
            pktLength];
        END;  -- Unmarshal record.actionClass.
      BEGIN  -- Unmarshal record.actionType: ActionType from pkt.data[pktLength].
        [record.actionType, pktLength] ← Lupine.UnmarshalAtom[pkt,
            pktLength];
        END;  -- Unmarshal record.actionType.
      BEGIN  -- Unmarshal record.actionInfo: ROPE from pkt.data[pktLength].
        [record.actionInfo, pktLength] ← Lupine.UnmarshalRope[pkt,
            pktLength, FALSE];
        END;  -- Unmarshal record.actionInfo.
      END;  -- OPEN record: report.
      END;  -- Unmarshal report.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb] ← ReportAction[localConversation, report, argPkt.reportToAll]
      ELSE [nb] ← ReportAction[localConversation, report, reportToAll];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- ReportActionStub.

  GetConversationInfoStub: --PROCEDURE [shh: SHHH, convID: ConversationID]
      -- RETURNS [nb: NB, cInfo: ConversationInfo]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    nb: NB;
    cInfo: ConversationInfo;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, convID (1): ConversationID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, cInfo] ←
      GetConversationInfo[localConversation, argPkt.convID];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal cInfo: ConversationInfo to pkt.data[pktLength].
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @cInfo, dataLength: SIZE[ConversationInfo], alwaysOnePkt:
          FALSE];
      BEGIN OPEN record: cInfo;
      BEGIN  -- Marshal record.subject: ROPE to pkt.data[pktLength].
        pktLength ← Lupine.MarshalRope[record.subject, pkt, pktLength,
            FALSE];
        END;  -- Marshal record.subject.
      BEGIN  -- Marshal record.urgency: Thrush.CallUrgency to pkt.data[pktLength].
        pktLength ← Lupine.MarshalAtom[record.urgency, pkt, pktLength];
        END;  -- Marshal record.urgency.
      BEGIN  -- Marshal record.alertKind: Thrush.AlertKind to pkt.data[pktLength].
        pktLength ← Lupine.MarshalAtom[record.alertKind, pkt, pktLength];
        END;  -- Marshal record.alertKind.
      END;  -- OPEN record: cInfo.
      END;  -- Marshal cInfo.
    RETURN[returnLength: pktLength];
    END;  -- GetConversationInfoStub.

  GetPartyInfoStub: --PROCEDURE [shh: SHHH, credentials: Credentials,
      -- nameReq: NameReq, allParties: BOOL]
    -- RETURNS [nb: NB, pInfo: PartyInfo]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    credentials: Credentials;
    nameReq: NameReq;
    allParties: BOOL;
    nb: NB;
    pInfo: PartyInfo;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, allParties (9): BOOL];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 10;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [credentials: credentials, allParties: allParties] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal nameReq: NameReq from pkt.data[pktLength].
      [nameReq, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal nameReq.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb, pInfo] ←
          GetPartyInfo[localConversation, argPkt.credentials, nameReq,
              argPkt.allParties]
      ELSE [nb, pInfo] ←
          GetPartyInfo[localConversation, credentials, nameReq, allParties];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal pInfo: PartyInfo to pkt.data[pktLength].
      pktLength ← MarshalPartyInfo[pInfo, pkt, pktLength];
      END;  -- Marshal pInfo.
    RETURN[returnLength: pktLength];
    END;  -- GetPartyInfoStub.

  GetKeyTableStub: --PROCEDURE [shh: SHHH, credentials: Credentials]
      -- RETURNS [nb: NB, keyTable: Thrush.KeyTable]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    nb: NB;
    keyTable: Thrush.KeyTable;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 9;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, keyTable] ←
      GetKeyTable[localConversation, argPkt.credentials];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal keyTable: Thrush.KeyTable to pkt.data[pktLength].
      pktLength ← MarshalThrushDotKeyTable[keyTable, pkt, pktLength];
      END;  -- Marshal keyTable.
    RETURN[returnLength: pktLength];
    END;  -- GetKeyTableStub.

  DescribePartyStub: --PROCEDURE [partyID: Thrush.PartyID, nameReq:
      -- NameReq] RETURNS [nb: NB, description: Thrush.ROPE]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    partyID: Thrush.PartyID;
    nameReq: NameReq;
    nb: NB;
    description: Thrush.ROPE;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, partyID (1): Thrush.PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [partyID: partyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal nameReq: NameReq from pkt.data[pktLength].
      [nameReq, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal nameReq.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    IF onePkt
      THEN [nb, description] ←
          DescribeParty[argPkt.partyID, nameReq]
      ELSE [nb, description] ←
          DescribeParty[partyID, nameReq];
    END;  -- OnePkt.
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal description: Thrush.ROPE to pkt.data[pktLength].
      pktLength ← Lupine.MarshalRope[description, pkt, pktLength, FALSE];
      END;  -- Marshal description.
    RETURN[returnLength: pktLength];
    END;  -- DescribePartyStub.

  RegisterServiceInterfaceStub: --PROCEDURE [shhh: SHHH, credentials:
      -- Credentials, interfaceSpecPattern: Thrush.InterfaceSpec]
    -- RETURNS [nb: NB, interfaceSpec: Thrush.InterfaceSpec]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    interfaceSpecPattern: Thrush.InterfaceSpec;
    nb: NB;
    interfaceSpec: Thrush.InterfaceSpec;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 9;
    BEGIN  -- Unmarshal interfaceSpecPattern: Thrush.InterfaceSpec
        -- from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @interfaceSpecPattern, dataLength: SIZE[Thrush.InterfaceSpec],
          alwaysOnePkt: TRUE];
      -- Restore garbled REFs to NIL following copy.
      BEGIN OPEN record: interfaceSpecPattern;
      BEGIN OPEN record: record.interfaceName;
      LOOPHOLE[record.type, LONG POINTER] ← NIL;
      LOOPHOLE[record.instance, LONG POINTER] ← NIL;
      END;  -- OPEN record: record.interfaceName.
      END;  -- OPEN record: interfaceSpecPattern.
      BEGIN OPEN record: interfaceSpecPattern;
      BEGIN  -- Unmarshal record.interfaceName: RPC.InterfaceName from
          -- pkt.data[pktLength].
        BEGIN OPEN record: record.interfaceName;
        BEGIN  -- Unmarshal record.type: ShortROPE from pkt.data[pktLength].
          [record.type, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength,
              TRUE];
          END;  -- Unmarshal record.type.
        BEGIN  -- Unmarshal record.instance: ShortROPE from pkt.data[pktLength].
          [record.instance, pktLength] ← Lupine.UnmarshalRope[pkt,
              pktLength, TRUE];
          END;  -- Unmarshal record.instance.
        END;  -- OPEN record: record.interfaceName.
        END;  -- Unmarshal record.interfaceName.
      END;  -- OPEN record: interfaceSpecPattern.
      END;  -- Unmarshal interfaceSpecPattern.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, interfaceSpec] ←
      RegisterServiceInterface[localConversation, argPkt.credentials,
          interfaceSpecPattern];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal interfaceSpec: Thrush.InterfaceSpec to pkt.data[pktLength].
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @interfaceSpec, dataLength: SIZE[Thrush.InterfaceSpec],
          alwaysOnePkt: FALSE];
      BEGIN OPEN record: interfaceSpec;
      BEGIN  -- Marshal record.interfaceName: RPC.InterfaceName to
          -- pkt.data[pktLength].
        BEGIN OPEN record: record.interfaceName;
        BEGIN  -- Marshal record.type: ShortROPE to pkt.data[pktLength].
          pktLength ← Lupine.MarshalRope[record.type, pkt, pktLength,
              TRUE];
          END;  -- Marshal record.type.
        BEGIN  -- Marshal record.instance: ShortROPE to pkt.data[pktLength].
          pktLength ← Lupine.MarshalRope[record.instance, pkt, pktLength,
              TRUE];
          END;  -- Marshal record.instance.
        END;  -- OPEN record: record.interfaceName.
        END;  -- Marshal record.interfaceName.
      END;  -- OPEN record: interfaceSpec.
      END;  -- Marshal interfaceSpec.
    RETURN[returnLength: pktLength];
    END;  -- RegisterServiceInterfaceStub.

  LookupServiceInterfaceStub: --PROCEDURE [shhh: SHHH, credentials:
      -- Credentials, serviceParty: PartyID, type: RPC.ShortROPE]
    -- RETURNS [nb: NB, interfaceSpec: Thrush.InterfaceSpec]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    type: RPC.ShortROPE;
    nb: NB;
    interfaceSpec: Thrush.InterfaceSpec;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, serviceParty (9): PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 11;
    BEGIN  -- Unmarshal type: RPC.ShortROPE from pkt.data[pktLength].
      [type, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, TRUE];
      END;  -- Unmarshal type.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, interfaceSpec] ←
      LookupServiceInterface[localConversation, argPkt.credentials,
          argPkt.serviceParty, type];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    BEGIN  -- Marshal interfaceSpec: Thrush.InterfaceSpec to pkt.data[pktLength].
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @interfaceSpec, dataLength: SIZE[Thrush.InterfaceSpec],
          alwaysOnePkt: FALSE];
      BEGIN OPEN record: interfaceSpec;
      BEGIN  -- Marshal record.interfaceName: RPC.InterfaceName to
          -- pkt.data[pktLength].
        BEGIN OPEN record: record.interfaceName;
        BEGIN  -- Marshal record.type: ShortROPE to pkt.data[pktLength].
          pktLength ← Lupine.MarshalRope[record.type, pkt, pktLength,
              TRUE];
          END;  -- Marshal record.type.
        BEGIN  -- Marshal record.instance: ShortROPE to pkt.data[pktLength].
          pktLength ← Lupine.MarshalRope[record.instance, pkt, pktLength,
              TRUE];
          END;  -- Marshal record.instance.
        END;  -- OPEN record: record.interfaceName.
        END;  -- Marshal record.interfaceName.
      END;  -- OPEN record: interfaceSpec.
      END;  -- Marshal interfaceSpec.
    RETURN[returnLength: pktLength];
    END;  -- LookupServiceInterfaceStub.

  RegisterKeyStub: --PROCEDURE [shh: SHHH, credentials: Credentials,
      -- key: Thrush.EncryptionKey]
    -- RETURNS [nb: NB, keyIndex: [0..15]]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials, key (9): Thrush.EncryptionKey];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        keyIndex (0): [0..15]];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 13;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, resPkt.keyIndex] ←
      RegisterKey[localConversation, argPkt.credentials, argPkt.key];
    pktLength ← 1;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- RegisterKeyStub.

  GetPartyStub: --PROCEDURE [shh: SHHH, partyID: PartyID, rName: ROPE,
      -- type: Thrush.PartyType]
    -- RETURNS [nb: NB, newPartyID: PartyID]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    partyID: PartyID;
    rName: ROPE;
    type: Thrush.PartyType;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, partyID (1): PartyID];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        newPartyID (0): PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay;
    pktLength: RpcPrivate.DataLength ← 3;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [partyID: partyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal rName: ROPE from pkt.data[pktLength].
      [rName, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal rName.
    BEGIN  -- Unmarshal type: Thrush.PartyType from pkt.data[pktLength].
      [type, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal type.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    IF onePkt
      THEN [nb, resPkt.newPartyID] ←
          GetParty[localConversation, argPkt.partyID, rName, type]
      ELSE [nb, resPkt.newPartyID] ←
          GetParty[localConversation, partyID, rName, type];
    END;  -- OnePkt.
    pktLength ← 2;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- GetPartyStub.

  GetPartyFromNumberStub: --PROCEDURE [shh: SHHH, partyID: PartyID,
      -- phoneNumber: Thrush.ROPE, description: ROPE]
    -- RETURNS [nb: NB, newPartyID: PartyID]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    partyID: PartyID;
    phoneNumber: Thrush.ROPE;
    description: ROPE;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, partyID (1): PartyID];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        newPartyID (0): PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay;
    pktLength: RpcPrivate.DataLength ← 3;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [partyID: partyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal phoneNumber: Thrush.ROPE from pkt.data[pktLength].
      [phoneNumber, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength,
          FALSE];
      END;  -- Unmarshal phoneNumber.
    BEGIN  -- Unmarshal description: ROPE from pkt.data[pktLength].
      [description, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength,
          FALSE];
      END;  -- Unmarshal description.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    IF onePkt
      THEN [nb, resPkt.newPartyID] ←
          GetPartyFromNumber[localConversation, argPkt.partyID, phoneNumber,
              description]
      ELSE [nb, resPkt.newPartyID] ←
          GetPartyFromNumber[localConversation, partyID, phoneNumber,
              description];
    END;  -- OnePkt.
    pktLength ← 2;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- GetPartyFromNumberStub.

  GetPartyFromFeepNumStub: --PROCEDURE [shh: SHHH, partyID: PartyID,
      -- feepNum: Thrush.ROPE]
    -- RETURNS [nb: NB, newPartyID: PartyID]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    partyID: PartyID;
    feepNum: Thrush.ROPE;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, partyID (1): PartyID];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        newPartyID (0): PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay;
    pktLength: RpcPrivate.DataLength ← 3;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [partyID: partyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal feepNum: Thrush.ROPE from pkt.data[pktLength].
      [feepNum, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal feepNum.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    IF onePkt
      THEN [nb, resPkt.newPartyID] ←
          GetPartyFromFeepNum[localConversation, argPkt.partyID, feepNum]
      ELSE [nb, resPkt.newPartyID] ←
          GetPartyFromFeepNum[localConversation, partyID, feepNum];
    END;  -- OnePkt.
    pktLength ← 2;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- GetPartyFromFeepNumStub.

  GetCurrentPartyStub: --PROCEDURE [shh: SHHH, smartsID: SmartsID]
      -- RETURNS [nb: NB, partyID: Thrush.PartyID]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, smartsID (1): SmartsID];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        partyID (0): Thrush.PartyID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb, resPkt.partyID] ←
      GetCurrentParty[localConversation, argPkt.smartsID];
    pktLength ← 2;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- GetCurrentPartyStub.

  GetNumbersForRNameStub: --PROCEDURE [shh: SHHH, rName: ROPE] RETURNS
      -- [fullRName: ROPE, number: ROPE, homeNumber: ROPE]-- RpcPrivate.Dispatcher
      =
    INLINE BEGIN
    rName: ROPE;
    fullRName: ROPE;
    number: ROPE;
    homeNumber: ROPE;
    pktLength: RpcPrivate.DataLength ← 1;
    BEGIN  -- Unmarshal rName: ROPE from pkt.data[pktLength].
      [rName, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal rName.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [fullRName, number, homeNumber] ←
      GetNumbersForRName[localConversation, rName];
    pktLength ← 0;
    BEGIN  -- Marshal fullRName: ROPE to pkt.data[pktLength].
      pktLength ← Lupine.MarshalRope[fullRName, pkt, pktLength, FALSE];
      END;  -- Marshal fullRName.
    BEGIN  -- Marshal number: ROPE to pkt.data[pktLength].
      pktLength ← Lupine.MarshalRope[number, pkt, pktLength, FALSE];
      END;  -- Marshal number.
    BEGIN  -- Marshal homeNumber: ROPE to pkt.data[pktLength].
      pktLength ← Lupine.MarshalRope[homeNumber, pkt, pktLength, FALSE];
      END;  -- Marshal homeNumber.
    RETURN[returnLength: pktLength];
    END;  -- GetNumbersForRNameStub.

  RegisterStub: --PROCEDURE [shh: SHHH, rName: ROPE, type: Thrush.PartyType,
      -- clonePartyID: PartyID, interface: SmartsInterfaceName, properties:
      -- SmartsProperties]
    -- RETURNS [nb: NB, credentials: Credentials]-- RpcPrivate.Dispatcher
        =
    INLINE BEGIN
    rName: ROPE;
    type: Thrush.PartyType;
    clonePartyID: PartyID;
    interface: SmartsInterfaceName;
    properties: SmartsProperties;
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, clonePartyID (1):
        PartyID];
    ResultOverlay: TYPE = MACHINE DEPENDENT RECORD [
        credentials (0): Credentials];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    resPkt: LONG POINTER TO ResultOverlay;
    pktLength: RpcPrivate.DataLength ← 3;
    BEGIN  -- OnePkt.
    onePkt: BOOLEAN = lastPkt;
    IF ~onePkt THEN BEGIN  -- Must move statics from pkt now.
      [clonePartyID: clonePartyID] ← argPkt↑;
      END;
    BEGIN  -- Unmarshal rName: ROPE from pkt.data[pktLength].
      [rName, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength, FALSE];
      END;  -- Unmarshal rName.
    BEGIN  -- Unmarshal type: Thrush.PartyType from pkt.data[pktLength].
      [type, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
      END;  -- Unmarshal type.
    BEGIN  -- Unmarshal interface: SmartsInterfaceName from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @interface, dataLength: SIZE[SmartsInterfaceName], alwaysOnePkt:
          FALSE];
      -- Restore garbled REFs to NIL following copy.
      BEGIN OPEN record: interface;
      LOOPHOLE[record.type, LONG POINTER] ← NIL;
      LOOPHOLE[record.instance, LONG POINTER] ← NIL;
      END;  -- OPEN record: interface.
      BEGIN OPEN record: interface;
      BEGIN  -- Unmarshal record.type: RPC.ShortROPE from pkt.data[pktLength].
        [record.type, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength,
            TRUE];
        END;  -- Unmarshal record.type.
      BEGIN  -- Unmarshal record.instance: RPC.ShortROPE from pkt.data[pktLength].
        [record.instance, pktLength] ← Lupine.UnmarshalRope[pkt, pktLength,
            TRUE];
        END;  -- Unmarshal record.instance.
      END;  -- OPEN record: interface.
      END;  -- Unmarshal interface.
    BEGIN  -- Unmarshal properties: SmartsProperties from pkt.data[pktLength].
      pktLength ← Lupine.CopyFromPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: @properties, dataLength: SIZE[SmartsProperties], alwaysOnePkt:
          FALSE];
      -- Restore garbled REFs to NIL following copy.
      BEGIN OPEN record: properties;
      LOOPHOLE[record.role, LONG POINTER] ← NIL;
      END;  -- OPEN record: properties.
      BEGIN OPEN record: properties;
      BEGIN  -- Unmarshal record.role: SmartsRole from pkt.data[pktLength].
        [record.role, pktLength] ← Lupine.UnmarshalAtom[pkt, pktLength];
        END;  -- Unmarshal record.role.
      END;  -- OPEN record: properties.
      END;  -- Unmarshal properties.
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    resPkt ← @pkt.data[0];
    IF onePkt
      THEN [nb, resPkt.credentials] ←
          Register[localConversation, rName, type, argPkt.clonePartyID,
              interface, properties]
      ELSE [nb, resPkt.credentials] ←
          Register[localConversation, rName, type, clonePartyID, interface,
              properties];
    END;  -- OnePkt.
    pktLength ← 8;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- RegisterStub.

  CheckInStub: --PROCEDURE [shh: SHHH, credentials: Credentials] RETURNS
      -- [nb: NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, credentials (1):
        Credentials];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 9;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb] ← CheckIn[localConversation, argPkt.credentials];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- CheckInStub.

  DeregisterStub: --PROCEDURE [shh: SHHH, smartsID: SmartsID] RETURNS
      -- [nb: NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    nb: NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, smartsID (1): SmartsID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb] ← Deregister[localConversation, argPkt.smartsID];
    pktLength ← 0;
    BEGIN  -- Marshal nb: NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- DeregisterStub.

  EnableStub: --PROCEDURE [shh: SHHH, smartsID: SmartsID] RETURNS [nb:
      -- Thrush.NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    nb: Thrush.NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, smartsID (1): SmartsID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb] ← Enable[localConversation, argPkt.smartsID];
    pktLength ← 0;
    BEGIN  -- Marshal nb: Thrush.NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- EnableStub.

  DisableStub: --PROCEDURE [shh: SHHH, smartsID: SmartsID] RETURNS
      -- [nb: Thrush.NB]-- RpcPrivate.Dispatcher =
    INLINE BEGIN
    nb: Thrush.NB;
    ArgumentOverlay: TYPE = MACHINE DEPENDENT RECORD [
        transferIndex (0): RpcControl.ProcedureIndex, smartsID (1): SmartsID];
    argPkt: LONG POINTER TO ArgumentOverlay = @pkt.data[0];
    pktLength: RpcPrivate.DataLength ← 3;
    Lupine.CheckPktLength[pkt: pkt, pktLength: pktLength];
    [nb] ← Disable[localConversation, argPkt.smartsID];
    pktLength ← 0;
    BEGIN  -- Marshal nb: Thrush.NB to pkt.data[pktLength].
      pktLength ← Lupine.MarshalAtom[nb, pkt, pktLength];
      END;  -- Marshal nb.
    RETURN[returnLength: pktLength];
    END;  -- DisableStub.


-- Marshall/Unmarshal procedures.
MarshalThrushDotConvEvent: PROC[value: Thrush.ConvEvent, pkt: RpcPrivate.RPCPkt,
    pktLength0: RpcPrivate.DataLength]
  RETURNS[pktLength: RpcPrivate.DataLength] = BEGIN
  pktLength ← pktLength0; {
  IF pktLength+1 > RpcPrivate.maxDataLength
    THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
  pkt.data[pktLength] ← value=NIL;  pktLength ← pktLength+1;
  IF value # NIL THEN
    BEGIN  -- Marshal value↑: Thrush.ConvEventBody to pkt.data[pktLength].
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: LOOPHOLE[value], dataLength: SIZE[Thrush.ConvEventBody],
          alwaysOnePkt: FALSE];
      BEGIN OPEN record: value↑;
      BEGIN  -- Marshal record.reason: Thrush.Reason to pkt.data[pktLength].
        pktLength ← Lupine.MarshalAtom[record.reason, pkt, pktLength];
        END;  -- Marshal record.reason.
      BEGIN  -- Marshal record.comment: Thrush.ROPE to pkt.data[pktLength].
        pktLength ← Lupine.MarshalRope[record.comment, pkt, pktLength,
            FALSE];
        END;  -- Marshal record.comment.
      END;  -- OPEN record: value↑.
      END;  -- Marshal value↑.
  };END;

MarshalThrushDotKeyTable: PROC[value: Thrush.KeyTable, pkt: RpcPrivate.RPCPkt,
    pktLength0: RpcPrivate.DataLength]
  RETURNS[pktLength: RpcPrivate.DataLength] = BEGIN
  pktLength ← pktLength0; {
  BEGIN  -- Marshal value↑: IV.KeyTableBody to pkt.data[pktLength].
    IF pktLength+3 > RpcPrivate.maxDataLength
      THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
    pkt.data[pktLength] ← value=NIL;  pktLength ← pktLength+1;
    IF value # NIL THEN BEGIN
      -- Record has a sequence, put its length up front.
      Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← LENGTH[DESCRIPTOR[value↑]];
      pktLength ← pktLength + 2;
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: LOOPHOLE[value], dataLength: SIZE[IV.KeyTableBody[LENGTH[DESCRIPTOR[value↑]]]],
          alwaysOnePkt: FALSE];
      END;  -- IF value # NIL.
    END;  -- Marshal value↑.
  };END;

MarshalPartyInfo: PROC[value: ThParty.PartyInfo, pkt: RpcPrivate.RPCPkt,
    pktLength0: RpcPrivate.DataLength]
  RETURNS[pktLength: RpcPrivate.DataLength] = BEGIN
  pktLength ← pktLength0; {
  BEGIN  -- Marshal value↑: ThParty.PartyInfoSeq to pkt.data[pktLength].
    IF pktLength+3 > RpcPrivate.maxDataLength
      THEN pktLength ← Lupine.StartNextPkt[pkt: pkt, pktLength: pktLength];
    pkt.data[pktLength] ← value=NIL;  pktLength ← pktLength+1;
    IF value # NIL THEN BEGIN
      -- Record has a sequence, put its length up front.
      Lupine.RpcPktDoubleWord[pkt, pktLength]↑ ← LENGTH[DESCRIPTOR[value↑]];
      pktLength ← pktLength + 2;
      pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
          dataAdr: LOOPHOLE[value], dataLength: SIZE[ThParty.PartyInfoSeq[LENGTH[DESCRIPTOR[value↑]]]],
          alwaysOnePkt: FALSE];
      BEGIN OPEN record: value↑;
      BEGIN  -- Marshal record.parties: SEQUENCE len: NAT OF ThParty.PartyInfoSpec
          -- to pkt.data[pktLength].
        -- The sequence's length was carried by its record.
        FOR element3: NAT IN [FIRST[NAT]..FIRST[NAT]+LENGTH[DESCRIPTOR[record.parties]])
            DO
          BEGIN  -- Marshal record.parties[element3]: ThParty.PartyInfoSpec
              -- to pkt.data[pktLength].
            pktLength ← Lupine.CopyToPkt[pkt: pkt, pktLength: pktLength,
                dataAdr: @record.parties[element3], dataLength: SIZE[ThParty.PartyInfoSpec],
                alwaysOnePkt: FALSE];
            BEGIN OPEN record: record.parties[element3];
            BEGIN  -- Marshal record.type: Thrush.PartyType to pkt.data[pktLength].
              pktLength ← Lupine.MarshalAtom[record.type, pkt, pktLength];
              END;  -- Marshal record.type.
            BEGIN  -- Marshal record.name: Thrush.ROPE to pkt.data[pktLength].
              pktLength ← Lupine.MarshalRope[record.name, pkt, pktLength,
                  FALSE];
              END;  -- Marshal record.name.
            END;  -- OPEN record: record.parties[element3].
            END;  -- Marshal record.parties[element3].
          ENDLOOP;  -- FOR element3.
        END;  -- Marshal record.parties.
      END;  -- OPEN record: value↑.
      END;  -- IF value # NIL.
    END;  -- Marshal value↑.
  };END;



-- No module initialization.

END.  -- ThPartyRpcServerImpl.