private void storeRequest(
     RequestCache rc,
     SIF_Request request,
     Query q,
     String msgID,
     String objectName)
 {
     //request.getSIF_Query().getSIF_QueryObject().setObjectName(objectName);
     request.SIF_Query.SIF_QueryObject.ObjectName = objectName;
     request.Header.SIF_MsgId = msgID;
     rc.StoreRequestInfo(request, q, null);
 }
        public void testPersistenceWithBadState()
        {
            //create new cache for agent
            RequestCache cache = RequestCache.GetInstance(fAgent);

            //create new queryobject
            SIF_QueryObject obj = new SIF_QueryObject("");
            //create query, telling it what type of query it is(passing it queryobj)
            SIF_Query query = new SIF_Query(obj);
            //create new sif request
            SIF_Request request = new SIF_Request();
            //set query property
            request.SIF_Query = query;

            Query q = new Query(StudentDTD.STUDENTPERSONAL);

            String testStateItem = Adk.MakeGuid();
            String requestMsgId = Adk.MakeGuid();
            String testObjectType = Adk.MakeGuid();

            TestState ts = new TestState();
            ts.State = testStateItem;
            ts.setCreateErrorOnRead(true);

            q.UserData = ts;
            storeRequest(cache, request, q, requestMsgId, testObjectType);

            cache.Close();

            // Create a new instance. This one should retrieve its settings from the persistence mechanism
            cache = RequestCache.GetInstance(fAgent);

            IRequestInfo ri = cache.GetRequestInfo(requestMsgId, null);

            //if state is null, should still return ri object
            Assertion.AssertNotNull("RequestInfo was null", ri);
            Assertion.AssertEquals("MessageId", requestMsgId, ri.MessageId);
            Assertion.AssertEquals("ObjectType", testObjectType, ri.ObjectType);
            ts = (TestState) ri.UserData;
            // In order for this to be a valid test, the TestState class should have thrown
            // an exception during deserialization and should be null here.
            Assertion.AssertNull("UserData should be null", ts);
        }
        public void testWithLegacyFile()
        {
            //assertStoredRequests(fRC, true);
            // Copy the legacy requests.adk file to the agent work directory
            //FileInfo legacyFile = new FileInfo("requests.adk");

            //Assertion.Assert("Saved legacy file does [not?] exist", legacyFile.Exists);
            //FileInfo copiedFile = new FileInfo(fAgent.HomeDir + Path.DirectorySeparatorChar + "work" + Path.DirectorySeparatorChar + "requests.adk");
            //if (copiedFile.Exists)
            //{
            //   copiedFile.Delete();
            //}

            //// Copy the file
            //legacyFile.CopyTo(copiedFile.FullName, true);

            // Now open up an instance of the request cache and verify that the contents are there

            fRC = RequestCache.GetInstance(fAgent);
            SIF_QueryObject obj = new SIF_QueryObject("");
            SIF_Query query = new SIF_Query(obj);
            SIF_Request request = new SIF_Request();
            request.SIF_Query = query;

            Query q;
            TestState ts;

            fMsgIds = new String[10];
            fStateObjects = new String[10];
            // Add 10 entries to the cache
            for (int i = 0; i < 10; i++)
            {
                ts = new TestState();
                ts.State = Adk.MakeGuid();
                fStateObjects[i] = (String) ts.State;
                q = new Query(StudentDTD.STUDENTPERSONAL);
                q.UserData = ts;
                fMsgIds[i] = Adk.MakeGuid();
                storeRequest(fRC, request, q, fMsgIds[i], "Object_" + i.ToString());
            }

            Assertion.AssertEquals("Active request count", 10, fRC.ActiveRequestCount);

            // Lookup each setting,
            for (int i = 0; i < 10; i++)
            {
                IRequestInfo reqInfo = fRC.LookupRequestInfo(fMsgIds[i], null);
                Assertion.AssertEquals("Initial lookup", "Object_" + i.ToString(), reqInfo.ObjectType);
            }

            // Lookup each setting,
            for (int i = 0; i < 10; i++)
            {
                IRequestInfo reqInfo = fRC.GetRequestInfo(fMsgIds[i], null);
                Assertion.AssertEquals("Initial lookup", "Object_" + i.ToString(), reqInfo.ObjectType);
            }

            // all messages should now be removed from the queue
            Assertion.AssertEquals("Cache should be empty", 0, fRC.ActiveRequestCount);

            // Now run one of our other tests
            testPersistence();
        }
        /**
           * Stores the items in the cache that will later be asserted
           * @param cache
           */
        private void storeAssertedRequests(RequestCache cache)
        {
            SIF_QueryObject obj = new SIF_QueryObject("");
            SIF_Query query = new SIF_Query(obj);
            SIF_Request request = new SIF_Request();
            request.SIF_Query = query;

            Query q;
            TestState ts;

            fMsgIds = new String[10];
            fStateObjects = new String[10];
            // Add 10 entries to the cache, interspersed with other entries that are removed
            for (int i = 0; i < 10; i++)
            {
                ts = new TestState();
                ts.State = Adk.MakeGuid();
                fStateObjects[i] = ts.State;
                q = new Query(StudentDTD.STUDENTPERSONAL);
                q.UserData = ts;

                String phantom1 = Adk.MakeGuid();
                String phantom2 = Adk.MakeGuid();
                storeRequest(cache, request, q, phantom1, "foo");
                fMsgIds[i] = Adk.MakeGuid();

                storeRequest(cache, request, q, fMsgIds[i], "Object_" + i.ToString());
                storeRequest(cache, request, q, phantom2, "bar");

                cache.GetRequestInfo(phantom1, null);
                cache.GetRequestInfo(phantom2, null);
            }
        }
        // TODO: Implement
        /*
        [Test]
        public void testReportPublishSIFExceptionAfterReportInfo()
        {
        ElementDef objType = SifDtd.SIF_REPORTOBJECT;
        ErrorMessageHandler handler = new ErrorMessageHandler( ErrorMessageHandler.BVR_SET_REPORT_INFO_THROW_EXCEPTION );
        fZone.setReportPublisher( handler, ADKFlags.PROV_NONE);

        TestProtocolHandler testProto = new TestProtocolHandler();
        testProto.open(fZone);
        MessageDispatcher testDispatcher = new MessageDispatcher( fZone );
        fZone.setDispatcher(testDispatcher);
        fZone.setProto(testProto);
        testDispatcher.dispatch( createSIF_Request( objType, ADK.makeGUID(), fZone ) );
        String msg = testProto.readMsg();
        assertNull(testProto.readMsg());
        fZone.log.info(msg);

        SIFParser parser = SIFParser.newInstance();
        SIFElement element = parser.parse(new StringReader(msg), fZone);
        assertTrue(element instanceof SIF_Response);
        SIF_Response response = (SIF_Response) element;
        assertTrue(response.getSIF_Error() != null);
        assertTrue(response.getSIF_Error().getSIF_Desc().startsWith("Blah"));
         }

        public void testReportPublishSIFExceptionAfterReportInfo() throws ADKException, IOException
         {
        ElementDef objType = SifDtd.SIF_REPORTOBJECT;
        ErrorMessageHandler handler = new ErrorMessageHandler( ErrorMessageHandler.BVR_SET_REPORT_INFO_THROW_EXCEPTION );
        fZone.setReportPublisher( handler, ADKFlags.PROV_NONE);

        TestProtocolHandler testProto = new TestProtocolHandler();
        testProto.open(fZone);
        MessageDispatcher testDispatcher = new MessageDispatcher( fZone );
        fZone.setDispatcher(testDispatcher);
        fZone.setProto(testProto);
        testDispatcher.dispatch( createSIF_Request( objType, ADK.makeGUID(), fZone ) );
        String msg = testProto.readMsg();
        assertNull(testProto.readMsg());
        fZone.log.info(msg);

        SIFParser parser = SIFParser.newInstance();
        SIFElement element = parser.parse(new StringReader(msg), fZone);
        assertTrue(element instanceof SIF_Response);
        SIF_Response response = (SIF_Response) element;
        assertTrue(response.getSIF_Error() != null);
        assertTrue(response.getSIF_Error().getSIF_Desc().startsWith("Blah"));
         }

        */
        private SIF_Request createSIF_Request(IElementDef objType)
        {
            SIF_Request request = new SIF_Request();
             request.Header.SIF_MsgId = MSG_GUID;
             request.Header.SIF_SourceId = "foo";
             request.SIF_MaxBufferSize = 32768;
             request.AddSIF_Version(new SIF_Version(Adk.SifVersion.ToString()));
             SIF_Query q = new SIF_Query();
             SIF_QueryObject sqo = new SIF_QueryObject();
             sqo.ObjectName = objType.Name;

             q.SIF_QueryObject = sqo;
             request.SIF_Query = q;

             return request;
        }
        public void testPersistenceWithRemoval()
        {
            fRC = RequestCache.GetInstance(fAgent);
            SIF_QueryObject obj = new SIF_QueryObject("");
            SIF_Query query = new SIF_Query(obj);
            SIF_Request request = new SIF_Request();

            request.SIF_Query = query;

            Query q = new Query(StudentDTD.STUDENTPERSONAL);
            String testStateItem = Adk.MakeGuid();
            TestState ts = new TestState();
            ts.State = testStateItem;
            q.UserData = ts;

            fMsgIds = new String[10];
            // Add 10 entries to the cache, interspersed with other entries that are removed
            for (int i = 0; i < 10; i++)
            {
                String phantom1 = Adk.MakeGuid();
                String phantom2 = Adk.MakeGuid();
                storeRequest(fRC, request, q, phantom1, "foo");
                fMsgIds[i] = Adk.MakeGuid();
                storeRequest(fRC, request, q, fMsgIds[i], "Object_" + i);
                storeRequest(fRC, request, q, phantom2, "bar");

                fRC.GetRequestInfo(phantom1, null);
                fRC.GetRequestInfo(phantom2, null);
            }

            // remove every other entry, close, re-open and assert that the correct entries are there
            for (int i = 0; i < 10; i += 2)
            {
                fRC.GetRequestInfo(fMsgIds[i], null);
            }

            Assertion.AssertEquals("Before closing Should have five objects", 5, fRC.ActiveRequestCount);
            fRC.Close();

            // Create a new instance. This one should retrieve its settings from the persistence mechanism
            fRC = RequestCache.GetInstance(fAgent);
            Assertion.AssertEquals("After Re-Openeing Should have five objects", 5, fRC.ActiveRequestCount);
            for (int i = 1; i < 10; i += 2)
            {
                IRequestInfo cachedInfo = fRC.GetRequestInfo(fMsgIds[i], null);
                Assertion.AssertNotNull("No cachedID returned for " + i, cachedInfo);
            }
            Assertion.AssertEquals("Should have zero objects", 0, fRC.ActiveRequestCount);
        }
        /// <summary>  Find the QueryResults object for a zone by searching up the message
        /// dispatching chain until a Zone, Topic, or Agent is found with a registered
        /// QueryResults implementation.
        /// 
        /// </summary>
        /// <param name="rsp">The SIF_Response message (if a SIF_Response was received).
        /// Either rsp or req must be specified, but not both.
        /// </param>
        /// <param name="req">The SIF_Request message (if a SIF_Request is being sent).
        /// Either rsp or req must be specified, but not both.
        /// </param>
        /// <param name="query">Only applicable when <i>req</i> is non-null: The Query
        /// associated with the SIF_Request
        /// </param>
        /// <param name="zone">The Zone to begin the search at
        /// </param>
        internal IQueryResults getQueryResultsTarget(SIF_Response rsp,
                                                      SIF_Request req,
                                                      IElementDef objType,
                                                      Query query,
                                                      IZone zone)
        {
            //
            //  - First check TrackQueryResults for a matching pending request
            //  - Next check the Topic, the Zone, and finally the Agent. The
            //    message is dispatched to the first one that results a
            //    QueryResults object
            //
            IQueryResults target = null;
            SifContext context = null;

            if (req != null)
            {
                //  First check TrackQueryResults
                string reqId = req.MsgId;

                // TODO: Implement SMB later
                //				TrackQueryResults tracker = (TrackQueryResults) TrackQueryResultsImpl.sRequestQueries[query];
                //				if (tracker != null)
                //				{
                //					TrackQueryResultsImpl.sRequestQueries.Remove( query );
                //					target = tracker;
                //				}
                //				else
                //				{
                SIF_Query q = req.SIF_Query;
                if (q == null)
                {
                    throw new SifException
                        (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                          "SIF_Request message missing mandatory element", "SIF_Query is required",
                          fZone);
                }

                SIF_QueryObject qo = q.SIF_QueryObject;
                if (qo == null)
                {
                    throw new SifException
                        (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                          "SIF_Request message missing mandatory element",
                          "SIF_QueryObject is required", fZone);
                }

                objType = Adk.Dtd.LookupElementDef(qo.ObjectName);
                if (objType == null)
                {
                    throw new SifException
                        (SifErrorCategoryCode.RequestResponse, SifErrorCodes.REQRSP_INVALID_OBJ_3,
                          "Agent does not support this object type", qo.ObjectName, fZone);
                }
                // Check to see if the Context is supported
                // TODO: Determine if a SIFException should be thrown at this point?
                try
                {

                    context = req.SifContexts[0];
                }
                catch (AdkNotSupportedException contextNotSupported)
                {
                    throw new SifException(
                            SifErrorCategoryCode.Generic,
                            SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4,
                            contextNotSupported.Message, fZone);
                }

            }
            else if (rsp != null)
            {
                // TODO Implement SMB
                //				//  First check TrackQueryResults object to see if it is expecting
                //				//  to be called for this SIF_Response
                //				string reqId = rsp.SIF_RequestMsgId;
                //				
                //				TrackQueryResults tracker = (TrackQueryResults) TrackQueryResultsImpl.sRequestMsgIds[reqId];
                //				if (tracker != null)
                //				{
                //					//  Dispatch to the TrackQueryResults object
                //					target = tracker;
                //				}

                // Check to see if the Context is supported
                // TODO: Determine if a SIFException should be thrown at this point?
                try
                {
                    context = rsp.SifContexts[0];
                }
                catch (AdkNotSupportedException contextNotSupported)
                {
                    throw new SifException(
                            SifErrorCategoryCode.Generic,
                            SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4,
                            contextNotSupported.Message, fZone);
                }


            }
            else
            {
                throw new ArgumentException
                    (
                    "A SIF_Request or SIF_Response object must be passed to getQueryResultsTarget");
            }

            if (target == null)
            {
                TopicImpl topic = (TopicImpl)fZone.Agent.TopicFactory.LookupInstance(objType, context);
                if (topic != null)
                {
                    target = topic.fQueryResults;
                }


                if (target == null)
                {
                    //  Next try the Zone...
                    target = fZone.GetQueryResults(context, objType);
                }
                if (target == null)
                {
                    //  Finally, try the Agent...
                    target = fZone.Agent.GetQueryResults(context, objType);
                }
            }

            return target;
        }
 /// <summary>  Store the request MsgId and associated SIF Data Object type in the cache</summary>
 public abstract IRequestInfo StoreRequestInfo( SIF_Request request,
                                                Query query,
                                                IZone zone );
        private void sendErrorResponse(SIF_Request req, SifException se, SifVersion renderAsVer, int maxBufSize)
        {

            DataObjectOutputStreamImpl outStream = DataObjectOutputStreamImpl.NewInstance();
            outStream.Initialize(fZone, (IElementDef[])null, req.SourceId, req.MsgId, renderAsVer, maxBufSize);

            SIF_Error err = new SIF_Error(
                (int)se.ErrorCategory,
                se.ErrorCode,
                se.ErrorDesc);
            err.SIF_ExtendedDesc = se.ErrorExtDesc;

            outStream.SetError(err);
            try
            {
                outStream.Close();
            }
            catch (Exception ignored)
            {
                fZone.Log.Warn("Ignoring exception in out.close()", ignored);
            }

            try
            {
                outStream.Commit();
            }
            catch (Exception ignored)
            {
                fZone.Log.Warn("Ignoring exception in out.commit()", ignored);
            }
        }
        /// <summary>  Dispatch a SIF_Request.
        /// 
        /// <b>When ALQ Disabled:</b> The SIF_Request is immediately dispatched to
        /// the Publisher of the associated topic. Only after the Publisher has
        /// returned a result does this method return, causing the SIF_Request to
        /// be acknowledged. The result data returned by the Publisher is handed to
        /// the zone's ResponseDelivery thread, which sends SIF_Response messages to
        /// the ZIS until all of the result data has been sent, potentially with
        /// multiple SIF_Response packets. Note without the ALQ, there is the
        /// potential for the agent to terminate before all data has been sent,
        /// causing some results to be lost. In this case the SIF_Request will have
        /// never been ack'd and will be processed again the next time the agent
        /// is started.
        /// 
        /// 
        /// <b>When ALQ Enabled:</b> The SIF_Request is placed in the ALQ where it
        /// will be consumed by the zone's ResponseDelivery thread at a later time.
        /// This method returns immediately, causing the SIF_Request to be
        /// acknowledged. The ResponseDelivery handles dispatching the request to
        /// the Publisher of the associated topic, and also handles returning
        /// SIF_Response packets to the ZIS. With the ALQ, the processing of the
        /// SIF_Request and the returning of all SIF_Response data is guaranteed
        /// because the original SIF_Request will not be removed from the ALQ until
        /// both of these activities have completed successfully (even over multiple
        /// agent sessions).
        /// 
        /// 
        /// Note that any error that occurs during a SIF_Request should result in a
        /// successful SIF_Ack (because the SIF_Request was received successfully),
        /// and a single SIF_Response with a SIF_Error payload. The SIF Compliance
        /// harness checks for this.
        /// 
        /// 
        /// </summary>
        /// <param name="req">The SIF_Request to process
        /// </param>
        private void dispatchRequest(SIF_Request req)
        {
            SifVersion renderAsVer = null;
            SIF_Query q = null;
            SIF_QueryObject qo = null;
            IElementDef typ = null;
            int maxBufSize = 0;
            bool rethrow = false;

            try
            {
                //	block thread until Zone.query() has completed in case it is in the
                //	midst of a SIF_Request and the destination of that request is this 
                //	agent (i.e. a request of self). This is done to ensure that we don't 
                //	receive the SIF_Request from the zone before the ADK and agent have 
                //	finished issuing it in Zone.query()
                fZone.WaitForRequestsToComplete();

                //
                //  Check SIF_Version. If the version is not supported by the Adk,
                //  fail the SIF_Request with an error SIF_Ack. If the version is
                //  supported, continue on; the agent may not support this version,
                //  but that will be determined later and will result in a SIF_Response
                //  with a SIF_Error payload.
                //
                SIF_Version[] versions = req.GetSIF_Versions();
                if (versions == null || versions.Length == 0)
                {
                    rethrow = true;
                    throw new SifException
                        (
                        SifErrorCategoryCode.Xml,
                        SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                        "SIF_Request/SIF_Version is a mandatory element",
                        fZone);
                }

                //  SIF_Version specifies the version of SIF that will be used to render
                //  the SIF_Responses
                // TODO: Add support for multiple SIF_Request versions
                renderAsVer = SifVersion.Parse(versions[0].Value);
                if (!Adk.IsSIFVersionSupported(renderAsVer))
                {
                    rethrow = true;
                    throw new SifException
                        (
                        SifErrorCategoryCode.RequestResponse,
                        SifErrorCodes.REQRSP_UNSUPPORTED_SIFVERSION_7,
                        "SIF_Version " + renderAsVer + " is not supported by this agent",
                        fZone);
                }

                //  Check max buffer size
                int? maximumBufferSize = req.SIF_MaxBufferSize;
                if (!maximumBufferSize.HasValue )
                {
                    rethrow = true;
                    throw new SifException
                        (
                        SifErrorCategoryCode.Xml,
                        SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                        "SIF_Request/SIF_MaxBufferSize is a mandatory element",
                        fZone);
                }
                maxBufSize = maximumBufferSize.Value;


                if (maxBufSize < 4096 || maxBufSize > Int32.MaxValue)
                {
                    throw new SifException
                        (
                        SifErrorCategoryCode.RequestResponse,
                        SifErrorCodes.REQRSP_UNSUPPORTED_MAXBUFFERSIZE_8,
                        "Invalid SIF_MaxBufferSize value (" + maxBufSize + ")",
                        "Acceptable range is 4096 to " + Int32.MaxValue,
                        fZone);
                }

                // Check to see if the Context is supported
                try
                {
                    IList<SifContext> contexts = req.SifContexts;
                }
                catch (AdkNotSupportedException contextNotSupported)
                {
                    throw new SifException(
                            SifErrorCategoryCode.Generic,
                            SifErrorCodes.GENERIC_CONTEXT_NOT_SUPPORTED_4,
                            contextNotSupported.Message, fZone);
                }


                //  Lookup the SIF_QueryObject
                q = req.SIF_Query;
                if (q == null)
                {
                    // If it's a SIF_ExtendedQuery or SIF_Example, throw the appropriate error
                    if (req.SIF_ExtendedQuery != null)
                    {
                        throw new SifException(
                            SifErrorCategoryCode.RequestResponse,
                            SifErrorCodes.REQRSP_NO_SUPPORT_FOR_SIF_EXT_QUERY,
                            "SIF_ExtendedQuery is not supported", fZone);
                    }
                    else
                    {
                        throw new SifException
                            (
                            SifErrorCategoryCode.Xml,
                            SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                            "SIF_Request/SIF_Query is a mandatory element",
                            fZone);
                    }
                }

                qo = q.SIF_QueryObject;
                if (qo == null)
                {
                    rethrow = true;
                    throw new SifException
                        (
                        SifErrorCategoryCode.Xml,
                        SifErrorCodes.XML_MISSING_MANDATORY_ELEMENT_6,
                        "SIF_Query/SIF_QueryObject is a mandatory element",
                        fZone);
                }

                //  Lookup the ElementDef for the requested object type
                typ = Adk.Dtd.LookupElementDef(qo.ObjectName);
                if (typ == null)
                {
                    throw new SifException
                        (
                        SifErrorCategoryCode.RequestResponse,
                        SifErrorCodes.REQRSP_INVALID_OBJ_3,
                        "Agent does not support this object type: " + qo.ObjectName,
                        fZone);
                }
            }
            catch (SifException se)
            {
                if (!rethrow)
                {
                    sendErrorResponse(req, se, renderAsVer, maxBufSize);
                }

                //	rethrow all errors at this point
                throw se;


                //                //  Capture the SifException so it can be written to the output stream
                //                //  and thus returned as the payload of the SIF_Response message later
                //                //  in this function.
                //                error = se;
                //                fZone.Log.Error("Error in dispatchRequest that will be put into the SIF_Response", se);
            }


            // For now, SIFContext is not repeatable in SIF Requests

            SifContext requestContext = req.SifContexts[0];
            Object target = null;

            //
            //  Lookup the Publisher for this object type using Topics, 
            // but only if the context is the Default context
            //


            if (typ != null && SifContext.DEFAULT.Equals(requestContext))
            {
                ITopic topic = null;
                topic = fZone.Agent.TopicFactory.LookupInstance(typ, requestContext);
                if (topic != null)
                {
                    target = topic.GetPublisher();
                }
            }


            if (target == null)
            {
                target = fZone.GetPublisher(requestContext, typ);
                

                if (target == null)
                {
                    //
                    //  No Publisher message handler found. Try calling the Undeliverable-
                    //  MessageHandler for the zone or agent. If none is registered,
                    //  return an error SIF_Ack indicating the object type is not
                    //  supported.
                    //
                    Boolean handled = false;
                    IUndeliverableMessageHandler errHandler = fZone.ErrorHandler;
                    if (errHandler != null)
                    {
                        SifMessageInfo msginfo = new SifMessageInfo(req, fZone);

                        handled = errHandler.OnDispatchError(req, fZone, msginfo);

                        //	Notify MessagingListeners...
                        foreach (IMessagingListener ml in GetMessagingListeners(fZone))
                        {
                            ml.OnMessageProcessed(SifMessageType.SIF_Request, msginfo);
                        }


                    }
                    if (!handled)
                    {
                        fZone.Log.Warn("Received a SIF_Request for " + qo.ObjectName + " (MsgId=" + req.MsgId + "), but no Publisher object is registered to handle it");

                        SifException sifEx = new SifException(
                           SifErrorCategoryCode.RequestResponse,
                           SifErrorCodes.REQRSP_INVALID_OBJ_3,
                           "Agent does not support this object type",
                           qo.ObjectName, fZone);
                        sendErrorResponse(req, sifEx, renderAsVer, maxBufSize);
                        throw sifEx;
                    }
                    else
                    {
#if PROFILED 
                                          ( BuildOptions.PROFILED )
							                        ProfilerUtils.profileStop();
#endif

                        return;
                    }
                }
            }


            //bool success;
            DataObjectOutputStreamImpl outStream = null;
            SifMessageInfo msgInfo = new SifMessageInfo(req, fZone);
            Query query = null;

            try
            {
                //  Convert SIF_Request/SIF_Query into a Query object
                if (q != null)
                {
                    query = new Query(q);
                }

                msgInfo.SIFRequestObjectType = typ;
            }
            catch (Exception thr)
            {
                fZone.Log.Debug(thr.ToString());
                SifException sifEx =
                    new SifException
                        (SifErrorCategoryCode.Xml, SifErrorCodes.XML_MALFORMED_2,
                          "Could not parse SIF_Query element", thr.Message, fZone, thr);
                sendErrorResponse(req, sifEx, renderAsVer, maxBufSize);
                throw sifEx;
            }

            try
            {

                outStream = DataObjectOutputStreamImpl.NewInstance();

                outStream.Initialize
                    (
                    fZone,
                    query, 
                    req.SourceId,
                    req.MsgId,
                    renderAsVer,
                    maxBufSize );

                //  Call the agent-supplied Publisher, or if we have an error, write
                //  that error to the output stream instead

               
                ((IPublisher)target).OnRequest(outStream, query, fZone, msgInfo);
                

                //	Notify MessagingListeners...
                NotifyMessagingListeners_OnMessageProcessed
                    (SifMessageType.SIF_Request, msgInfo);

            }
            catch (SifException se)
            {
                //  For a SIF_Request, a SifException (other than a Transport Error)
                //  does not mean to return an error ack but instead to return a
                //  valid SIF_Response with a SIF_Error payload (see the SIF
                //  Specification). Transport Errors must be returned to the ZIS so
                //  that the message will be retried later.
                //
                if (se.Retry || se.ErrorCategory == SifErrorCategoryCode.Transport)
                {
                    //success = false;
                    //retry was requested, so we have to tell the output stream to not send an empty response
                    outStream.DeferResponse();
                    throw;
                }

                outStream.SetError(se.Error);
            }
            catch (AdkException adke)
            {
                //	If retry requested, throw a Transport Error back to the ZIS
                //	instead of returning a SIF_Error in the SIF_Response payload
                if (adke.Retry)
                {
                    //success = false;
                    //retry was requested, so we have to tell the output stream to not send an empty response
                    outStream.DeferResponse();
                    throw;
                }

                //	Return SIF_Error payload in SIF_Response
                SIF_Error err = new SIF_Error();
                err.SIF_Category = (int)SifErrorCategoryCode.Generic;
                err.SIF_Code = SifErrorCodes.GENERIC_GENERIC_ERROR_1;
                err.SIF_Desc = adke.Message;

                outStream.SetError(err);
            }
            catch (Exception thr)
            {
                SIF_Error err = new SIF_Error();
                err.SIF_Category = (int)SifErrorCategoryCode.Generic;
                err.SIF_Code = SifErrorCodes.GENERIC_GENERIC_ERROR_1;
                err.SIF_Desc = "Agent could not process the SIF_Request at this time";

                err.SIF_ExtendedDesc = "Exception in " +
                                        "Publisher.onRequest" +
                                       " message handler: " + thr.ToString();

                outStream.SetError(err);
            }
            finally
            {
                try
                {
                    outStream.Close();
                }
                catch
                {
                    // Do Nothing
                }

                try
                {
                    outStream.Commit();
                }
                catch
                {
                    /* Do Nothing */
                }
#if PROFILED
				ProfilerUtils.profileStop();
#endif
                outStream.Dispose();
            }
        }
        /**
         *  SIF_Request
         */
        public SIF_Ack SifRequest(IZone zone, Query query, String destinationId, String sifMsgId)
        {
            //  Send SIF_Request...
            SIF_Request msg = new SIF_Request();
            // Find the maxmimum requested version and set the version of the message to lower
            // if the version is currently higher than the highest requested version.
            // In other words, if the Adk is initialized to 2.0, but the highest requested version
            // is 1.5r1, set the message version to 1.5r1
            SifVersion highestRequestVersion = SifVersion.SIF11;
            if (query.ObjectType == InfraDTD.SIF_ZONESTATUS)
            {
                // This query will be satisfied by the ZIS. Use the ZIS compatibility
                // version, which returns the highest version supported by the ZIS
                // (Default to Adk.SIFVersion() if not specified in the config)
                highestRequestVersion = ((ZoneImpl)zone).HighestEffectiveZISVersion;
                msg.AddSIF_Version(new SIF_Version(highestRequestVersion));
            }
            else
            {
                SifVersion[] requestVersions = query.SifVersions;
            if( requestVersions.Length > 0 ){
                // If the Query has one or more SIFVersions set, use them,
                // and also add [major].*
                foreach( SifVersion version in requestVersions ){
                    msg.AddSIF_Version(  new SIF_Version( version ) );
                    if( version.CompareTo( highestRequestVersion ) > 0 ){
                        highestRequestVersion = version;
                    }
                }
            } else {
                highestRequestVersion = Adk.SifVersion;
                if( highestRequestVersion.Major == 1 ){
                    msg.AddSIF_Version(  new SIF_Version( highestRequestVersion ) );
                } else {
                    // 2.0 and greater, request all data using
                    // [major].*, with 2.0r1 as the message version
                    // This allows for maximum compatibility will all 2.x providers
                    msg.AddSIF_Version( new SIF_Version( highestRequestVersion.Major + ".*" ));
                    msg.SifVersion = SifVersion.GetEarliest( highestRequestVersion.Major );
                }
            }

            }

            AgentProperties zoneProperties = zone.Properties;

            if (zoneProperties.OverrideSifMessageVersionForSifRequests != null)
            {
                //There is a property in Agent.cfg that can be used to override the message version from the
                //default of 2.0r1 This is needed to pass the test harness for 2.3
                msg.SifVersion = SifVersion.Parse(zoneProperties.OverrideSifMessageVersionForSifRequests);
            }

            else if(msg.SifVersion.CompareTo(highestRequestVersion) > 0)
            {
                // The current version of the SIF_Message is higher than the highest
                // requested version. Back the version number of message down to match
                msg.SifVersion = highestRequestVersion;
            }

            msg.SIF_MaxBufferSize = zone.Properties.MaxBufferSize;

            SIF_Query sifQ = CreateSIF_Query(query, highestRequestVersion, zone);
            msg.SIF_Query = sifQ;

            SIF_Header msgHeader = msg.Header;

            if (destinationId != null)
            {
                msgHeader.SIF_DestinationId = destinationId;
            }
            if (sifMsgId != null)
            {
                msgHeader.SIF_MsgId = sifMsgId;
            }

            // Set the SIF_Context
            msgHeader.SIF_Contexts = new SIF_Contexts(
                            new SIF_Context(query.SifContext.Name));

            return ((ZoneImpl)zone).Dispatcher.send(msg);
        }
        public override IRequestInfo StoreRequestInfo(SIF_Request request,
                                                       Query q,
                                                       IZone zone)
        {
            // validate that the userdata supplied with the query is serializable
            if (q.UserData != null)
            {
                Type userDataType = q.UserData.GetType();
                if (!userDataType.IsSerializable)
                {
                    throw new ArgumentException
                        ("Query.UserData contains " + userDataType.AssemblyQualifiedName +
                          " which is not serializable");
                }
            }

            try
            {
                RequestCacheFileEntry entry = new RequestCacheFileEntry(true);
                entry.SetObjectType(request.SIF_Query.SIF_QueryObject.ObjectName);
                entry.SetMessageId(request.MsgId);
                entry.SetUserData(q.UserData);
                Store(fFile, entry);
                return entry;
            }
            catch (Exception thr)
            {
                throw new AdkException
                    ("Error writing to SIF_Request ID cache (MsgId: " + request.MsgId + ") " + thr,
                      zone, thr);
            }
        }
        private void SetRequestPolicy( SIF_Request request, IZone zone )
        {
            SIF_Query query = request.SIF_Query;
            if( query == null ) {
            // SIF_ExtendedQuery and SIF_Example are not supported by ADK Policy yet
            return;
            }

            //
            // Object Request Policy
            //
            // Determine if there is policy in effect for this Query
            //
            String objectName = query.SIF_QueryObject.ObjectName;
            ObjectRequestPolicy requestPolicy = fPolicyFactory.GetRequestPolicy( zone, objectName );
            if( requestPolicy != null ){

            //
            // SIF_Request/SIF_Version policy
            //
            String requestVersions = requestPolicy.RequestVersion;
            if( requestVersions != null ){
                if( (Adk.Debug & AdkDebugFlags.Policy ) > 0 ){
                    zone.Log.Info( "POLICY: Setting SIF_Request/SIF_Version to " + requestVersions );
                }
                // Clear the list of SIF Versions
                foreach( SIF_Version existingVersion in request.GetSIF_Versions() ){
                    request.RemoveChild( existingVersion );
                }

                // The version will be a comma-delimited list. Set each of these
                // as SIF_Version elements, but also try to derive the most logical
                // version element to set the SIF Message/@Version attribute to
                // NOTE: Someone could theoretically set versions incorrectly, such
                // as "1.1,1.5r1". Multiple SIF_Version elements are not supported in
                // SIF 1.x, but we won't bother with validating incorrect settings. Policy
                // is power in the configurator's hands to use or abuse.

                String[] versions = requestVersions.Split( ',' );
                String lowestVersion = versions[0];
                foreach( String version in versions ){
                    String ver = version.Trim();
                    request.AddSIF_Version(new SIF_Version(ver));
                    if (lowestVersion.CompareTo(ver) > 0)
                    {
                        lowestVersion = ver;
                    }
                }

                // Determine how the SIF_Message/@Version should be set to
                //  * If the policy is set to a single version, use it
                //  * If a list, use the lowest
                //  * If *, ignore
                //  * if [major].*, use the lowest version supported
                if( lowestVersion.Length > 0  ){
                    SifVersion newMsgVersion = null;
                    if( lowestVersion.EndsWith( "*" ) ){
                        try
                        {
                            // 2.*, requests go out with a message version of 2.0r1
                            int major = int.Parse(  lowestVersion.Substring( 0, 1 ) );
                            newMsgVersion = SifVersion.GetEarliest( major );

                        } catch( FormatException iae ){
                            zone.Log.Warn(
                                    "POLICY: Error parsing ObjectRequestPolicy version '" +
                                    requestVersions + "' : " +
                                    iae.Message, iae );
                        }

                    } else {
                        try
                        {
                            newMsgVersion = SifVersion.Parse( lowestVersion );
                        } catch( FormatException iae ){
                            zone.Log.Warn(
                                    "POLICY: Error parsing ObjectRequestPolicy version '" +
                                    requestVersions + "' : " +
                                    iae.Message, iae );
                        }
                    }
                    if( newMsgVersion != null ){
                        if( (Adk.Debug & AdkDebugFlags.Policy ) > 0 ){
                            zone.Log.Info( "POLICY: Setting SIF_Messaage/@Version to " + newMsgVersion );
                        }
                        request.SifVersion = newMsgVersion;
                    }
                }
            }

            //
            // SIF_DestinationID policy
            //
            String requestSourceId = requestPolicy.RequestSourceId ;
            if( requestSourceId != null ){
                if( (Adk.Debug & AdkDebugFlags.Policy) > 0 ){
                    zone.Log.Info( "POLICY: Setting SIF_Request SIF_DestinationID to " + requestPolicy.RequestSourceId );
                }
                request.SIF_Header.SIF_DestinationId = requestSourceId;
            }
            }
        }