qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rupertlssm...@apache.org
Subject svn commit: r612874 [3/5] - in /incubator/qpid/branches/M2.1/dotnet: Qpid.Buffer.Tests/Properties/ Qpid.Buffer/Properties/ Qpid.Client.Tests/Properties/ Qpid.Client.Transport.Socket.Blocking/Properties/ Qpid.Client/Properties/ Qpid.Codec/Properties/ Qp...
Date Thu, 17 Jan 2008 17:13:23 GMT
Added: incubator/qpid/branches/M2.1/dotnet/Qpid.Integration.Tests/framework/alljava.csx
URL: http://svn.apache.org/viewvc/incubator/qpid/branches/M2.1/dotnet/Qpid.Integration.Tests/framework/alljava.csx?rev=612874&view=auto
==============================================================================
--- incubator/qpid/branches/M2.1/dotnet/Qpid.Integration.Tests/framework/alljava.csx (added)
+++ incubator/qpid/branches/M2.1/dotnet/Qpid.Integration.Tests/framework/alljava.csx Thu Jan 17 09:13:11 2008
@@ -0,0 +1,7851 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// Assertion models an assertion on a test <see cref="Circuit"/>.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities
+    /// <tr><td> Indicate whether or not the assertion passes when applied.
+    /// </table>
+    /// </summary>
+    public interface Assertion
+    {
+        /// <summary>
+        /// Applies the assertion.
+        /// </summary>
+        /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+        public bool apply();
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// AssertionBase is a base class for implenmenting assertions. It provides a mechanism to store error messages, and
+    /// report all error messages when its <see cref="#ToString()"/> method is called.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Collect error messages.
+    /// </table>
+    /// </summary>
+    public abstract class AssertionBase : Assertion
+    {
+        /// <summary> Holds the error messages. </summary>
+        IList<String> errors = new LinkedList<String>();
+
+        /// <summary>
+        /// Adds an error message to the assertion.
+        /// </summary>
+        /// <param name="error"> An error message to add to the assertion. </param>
+        public void addError(string error)
+        {
+            errors.add(error);
+        }
+
+        /// <summary>
+        /// Prints all of the error messages in the assertion into a string.
+        /// </summary>
+        /// <return> All of the error messages in the assertion as a string. </return>
+        public string ToString()
+        {
+            string result = "";
+
+            for (string error : errors)
+            {
+                result += error;
+            }
+
+            return result;
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// BrokerLifecycleAware is an awareness interface implemented by test cases that can run control the life-cycle of
+    /// the brokers on which they run. Its purpose is to expose additional instrumentation of brokers during testing, that
+    /// enables tests to use an automated failure mechanism to simulate broker failures, and to re-start failed brokers.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Indicate whether or not a test case is using an in-vm broker.
+    /// <tr><td> Track which in-vm broker is currently in use.
+    /// <tr><td> Accept setting of a failure mechanism. <td> <see cref="CauseFailure"/>.
+    /// </table>
+    /// </summary>
+    ///
+    /// <remarks> Need to think about how to present the brokers through this interface. Thinking numbering the available
+    ///       brokers from 1 will do. Then can kill 1 and assume failing onto 2. Restart 1 and kill 2 and fail back onto
+    ///       1 again? </remarks>
+    public interface BrokerLifecycleAware
+    {
+        public void setInVmBrokers();
+
+        /// <summary>
+        /// Indicates whether or not a test case is using in-vm brokers.
+        /// </summary>
+        /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+        public bool usingInVmBroker();
+
+        /// <summary>
+        /// Sets the currently live in-vm broker.
+        /// </summary>
+        /// <param name="i"> The currently live in-vm broker. </param>
+        public void setLiveBroker(int i);
+
+        /// <summary>
+        /// Reports the currently live in-vm broker.
+        /// </summary>
+        /// <return> The currently live in-vm broker. </return>
+        public int getLiveBroker();
+
+        /// <summary>
+        /// Accepts a failure mechanism.
+        /// </summary>
+        /// <param name="failureMechanism"> The failure mechanism. </param>
+        public void setFailureMechanism(CauseFailure failureMechanism);
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// CauseFailure provides a method to cause a failure in a messaging broker, usually used in conjunction with fail-over
+    /// or other failure mode testing. In some cases failures may be automated, for example by shutting down an in-vm broker,
+    /// or by sending a special control signal to a broker over a network connection. In other cases, it may be preferable
+    /// to ask a user interactively to cause a failure scenario, in which case an implementation may display a prompt or
+    /// dialog box asking for notification once the failure has been caused. The purpose of this interface is to abstract
+    /// the exact cause and nature of a failure out of failure test cases.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities
+    /// <tr><td> Cause messaging broker failure.
+    /// </table>
+    /// </summary>
+    public interface CauseFailure
+    {
+        /// <summary> Causes the active message broker to fail. </summary>
+        void causeFailure();
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.CauseFailure;
+
+using java.io.IOException;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// Causes a message broker failure by interactively prompting the user to cause it.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Cause messaging broker failure.
+    /// </table>
+    /// </summary>
+    public class CauseFailureUserPrompt : CauseFailure
+    {
+        /// <summary> Causes the active message broker to fail.</summary>
+        public void causeFailure()
+        {
+            waitForUser("Cause a broker failure now, then press Return.");
+        }
+
+        /// <summary>
+        /// Outputs a prompt to the console and waits for the user to press return.
+        /// </summary>
+        /// <param name="prompt"> The prompt to display on the console. </param>
+        private void waitForUser(string prompt)
+        {
+            System.out.println(prompt);
+
+            try
+            {
+                System.in.read();
+            }
+            catch (IOException e)
+            {
+                // Ignored.
+            }
+
+            System.out.println("Continuing.");
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// A Circuit is the basic test unit against which test cases are to be written. A circuit consists of two 'ends', an
+    /// instigating 'publisher' end and a more passive 'receivers' end.
+    ///
+    /// <p/>Once created, the life-cycle of a circuit may be controlled by <see cref="#start()"/>ing it, or <see cref="#close()"/>ing it.
+    /// Once started, the circuit is ready to send messages over. Once closed the circuit can no longer be used.
+    ///
+    /// <p/>The state of the circuit may be taken with the <see cref="#check()"/> method, and asserted against by the
+    /// <see cref="#applyAssertions(System.Collections.Generic.IList)"/> method.
+    ///
+    /// <p/>There is a default test procedure which may be performed against the circuit. The outline of this procedure is:
+    ///
+    /// <p/><pre>
+    /// Start the circuit.
+    /// Send test messages.
+    /// Request a status report.
+    /// Assert conditions on the publishing end of the circuit.
+    /// Assert conditions on the receiving end of the circuit.
+    /// Close the circuit.
+    /// Pass with no failed assertions or fail with a list of failed assertions.
+    /// </pre>
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities
+    /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+    /// <tr><td> Start the circuit running.
+    /// <tr><td> Close the circuit down.
+    /// <tr><td> Take a reading of the circuits state.
+    /// <tr><td> Apply assertions against the circuits state.
+    /// <tr><td> Send test messages over the circuit.
+    /// <tr><td> Perform the default test procedue on the circuit.
+    /// </table>
+    /// </summary>
+    public interface Circuit
+    {
+        /// <summary>
+        /// Gets the interface on the publishing end of the circuit.
+        /// </summary>
+        /// <return> The publishing end of the circuit. </return>
+        public Publisher getPublisher();
+
+        /// <summary>
+        /// Gets the interface on the receiving end of the circuit.
+        /// </summary>
+        /// <return> The receiving end of the circuit. </return>
+        public Receiver getReceiver();
+
+        /// <summary>
+        /// Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+        public void start();
+
+        /// <summary>
+        /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+        /// into a report, against which assertions may be checked.
+        public void check();
+
+        /// <summary>
+        /// Closes the circuit. All associated resources are closed.
+        public void close();
+
+        /// <summary>
+        /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+        /// this, to ensure that the circuit has gathered its state into a report to assert against.
+        /// </summary>
+        /// <param name="assertions"> The list of assertions to apply to the circuit. </param>
+        ///
+        /// <return> Any assertions that failed. </return>
+        public IList<Assertion> applyAssertions(List<Assertion> assertions);
+
+        /// <summary>
+        /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+        /// </summary>
+        /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+        /// <param name="assertions">  The list of assertions to apply. </param>
+        ///
+        /// <return> Any assertions that failed. </return>
+        public IList<Assertion> test(int numMessages, List<Assertion> assertions);
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// A CircuitEnd is a pair consisting of one message producer and one message consumer, that represents one end of a
+    /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+    /// the consumer and producer are instantiated and configured.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities
+    /// <tr><td> Provide a message producer for sending messages.
+    /// <tr><td> Provide a message consumer for receiving messages.
+    /// </table>
+    /// </summary>
+    ///
+    /// <remarks> Update the <see cref="org.apache.qpid.util.ConversationFactory"/> so that it accepts these as the basic conversation
+    /// connection units.</remarks>
+    public interface CircuitEnd
+    {
+        /// <summary>
+        /// Gets the message producer at this circuit end point.
+        /// </summary>
+        /// <return> The message producer at with this circuit end point. </return>
+        public MessageProducer getProducer();
+
+        /// <summary>
+        /// Gets the message consumer at this circuit end point.
+        /// </summary>
+        /// <return> The message consumer at this circuit end point. </return>
+        public MessageConsumer getConsumer();
+
+        /// <summary>
+        /// Send the specified message over the producer at this end point.
+        /// </summary>
+        /// <param name="message"> The message to send. </param>
+        ///
+        /// <exception cref="JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+        public void send(Message message) throws JMSException;
+
+        /// <summary>
+        /// Gets the JMS Session associated with this circuit end point.
+        /// </summary>
+        /// <return> The JMS Session associated with this circuit end point. </return>
+        public Session getSession();
+
+        /// <summary>
+        /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+        /// </summary>
+        /// <exception cref="JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+        public void close() throws JMSException;
+
+        /// <summary>
+        /// Returns the message monitor for reporting on received messages on this circuit end.
+        /// </summary>
+        /// <return> The message monitor for this circuit end. </return>
+        public MessageMonitor getMessageMonitor();
+
+        /// <summary>
+        /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+        /// </summary>
+        /// <return> The exception monitor for this circuit end. </return>
+        public ExceptionMonitor getExceptionMonitor();
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+    /// <summary>
+    /// A CircuitEndBase is a pair consisting of one message producer and one message consumer, that represents one end of a
+    /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+    /// the consumer and producer are instantiated and configured.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities
+    /// <tr><td> Provide a message producer for sending messages.
+    /// <tr><td> Provide a message consumer for receiving messages.
+    /// </table>
+    /// </summary>
+    public class CircuitEndBase : CircuitEnd
+    {
+        /// <summary> Holds the single message producer. </summary>
+        MessageProducer producer;
+
+        /// <summary> Holds the single message consumer. </summary>
+        MessageConsumer consumer;
+
+        /// <summary> Holds the controlSession for the circuit end. </summary>
+        Session session;
+
+        /// <summary> Holds the message monitor for the circuit end. </summary>
+        MessageMonitor messageMonitor;
+
+        /// <summary> Holds the exception monitor for the circuit end. </summary>
+        ExceptionMonitor exceptionMonitor;
+
+        /// <summary>
+        /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+        /// for messages and exceptions received by the circuit end.
+        /// </summary>
+        /// <param name="producer">         The message producer for the circuit end point. </param>
+        /// <param name="consumer">         The message consumer for the circuit end point. </param>
+        /// <param name="session">          The controlSession for the circuit end point. </param>
+        /// <param name="messageMonitor">   The monitor to notify of all messages received by the circuit end. </param>
+        /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+        public CircuitEndBase(MessageProducer producer, MessageConsumer consumer, Session session, MessageMonitor messageMonitor,
+                              ExceptionMonitor exceptionMonitor)
+        {
+            this.producer = producer;
+            this.consumer = consumer;
+            this.session = session;
+
+            this.messageMonitor = messageMonitor;
+            this.exceptionMonitor = exceptionMonitor;
+        }
+
+        /// <summary>
+        /// Gets the message producer at this circuit end point.
+        /// </summary>
+        /// <return> The message producer at with this circuit end point. </return>
+        public MessageProducer getProducer()
+        {
+            return producer;
+        }
+
+        /// <summary>
+        /// Gets the message consumer at this circuit end point.
+        /// </summary>
+        /// <return> The message consumer at this circuit end point. </return>
+        public MessageConsumer getConsumer()
+        {
+            return consumer;
+        }
+
+        /// <summary>
+        /// Send the specified message over the producer at this end point.
+        /// </summary>
+        /// <param name="message"> The message to send. </param>
+        /// <exception cref="javax.jms.JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+        public void send(Message message) throws JMSException
+        {
+            producer.send(message);
+        }
+
+        /// <summary>
+        /// Gets the JMS Session associated with this circuit end point.
+        /// </summary>
+        /// <return> The JMS Session associated with this circuit end point. </return>
+        public Session getSession()
+        {
+            return session;
+        }
+
+        /// <summary>
+        /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+        /// </summary>
+        /// <exception cref="javax.jms.JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+        public void close() throws JMSException
+        {
+            if (producer != null)
+            {
+                producer.close();
+            }
+
+            if (consumer != null)
+            {
+                consumer.close();
+            }
+        }
+
+        /// <summary>
+        /// Returns the message monitor for reporting on received messages on this circuit end.
+        /// </summary>
+        /// <return> The message monitor for this circuit end. </return>
+        public MessageMonitor getMessageMonitor()
+        {
+            return messageMonitor;
+        }
+
+        /// <summary>
+        /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+        /// </summary>
+        /// <return> The exception monitor for this circuit end. </return>
+        public ExceptionMonitor getExceptionMonitor()
+        {
+            return exceptionMonitor;
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+    /// <summary>
+    /// ClockSynchFailureException represents failure of a <see cref="ClockSynchronizer"/> to achieve synchronization. For example,
+    /// this could be because a reference signal is not available, or because a desired accurracy cannot be attained.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Represent failure to achieve synchronization.
+    /// </table>
+    /// </summary>
+    public class ClockSynchFailureException extends Exception
+    {
+        /// <summary>
+        /// Creates a clock synch failure exception.
+        /// </summary>
+        /// <param name="message"> The detail message (which is saved for later retrieval by the <see cref="#getMessage()"/> method). </param>
+        /// <param name="cause">   The cause (which is saved for later retrieval by the <see cref="#getCause()"/> method).  (A <tt>null</tt>
+        ///                        value is permitted, and indicates that the cause is nonexistent or unknown.)</param>
+        public ClockSynchFailureException(string message, Throwable cause)
+        {
+            super(message, cause);
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+    /// <summary>
+    /// ClockSynchronizer provides an interface through which two nodes may synchronize their clocks. It is expected that one
+    /// node will act as the reference clock, to which no delta need be applied, and the other node will act as the slave,
+    /// and which must apply a delta to its local clock to get a clock synchronized with the reference.
+    ///
+    /// <p/>The slave side will initiate the computation of a clock delta by calling the <see cref="#synch"/> method. This method
+    /// will not return until the delta has been computed, at which point there is a method to return its value, as well as
+    /// an estimate of the likely error (usually one standard deviation), in the synchronization. For convenience there is a
+    /// <see cref="#nanoTime"/> method to return the value of System.nanoTime() with the delta added in.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Trigger a clock synchronization.
+    /// <tr><td> Compute a clock delta to apply to the local clock.
+    /// <tr><td> Estimate the error in the synchronzation.
+    /// </table>
+    /// </summary>
+    public interface ClockSynchronizer
+    {
+        /// <summary>
+        /// The slave side should call this to copute a clock delta with the reference.
+        /// </summary>
+        /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+        public void synch() throws ClockSynchFailureException;
+
+        /// <summary>
+        /// Gets the clock delta in nano seconds.
+        /// </summary>
+        /// <return> The clock delta in nano seconds. </return>
+        public long getDelta();
+
+        /// <summary>
+        /// Gets an estimate of the clock error in nan seconds.
+        /// </summary>
+        /// <return> An estimate of the clock error in nan seconds. </return>
+        public long getEpsilon();
+
+        /// <summary>
+        /// Gets the local clock time with any computed delta added in.
+        /// </summary>
+        /// <return> The local clock time with any computed delta added in. </return>
+        public long nanoTime();
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+using uk.co.thebadgerset.junit.extensions.Throttle;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+    /// <summary>
+    /// ClockSynchThread is a convenient utility for running a thread that periodically synchronizes the clock against
+    /// a reference. Supply it with a <see cref="ClockSynchronizer"/> and a <see cref="Throttle"/> and it will continually keep the
+    /// clock up-to-date at a rate determined by the throttle.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Continually sychronize the clock at a throttled rate.
+    /// </table>
+    /// </summary>
+    public class ClockSynchThread extends Thread : ShutdownHookable
+    {
+        /// <summary> Used for debugging. </summary>
+        private static ILog log = LogManager.GetLogger(typeof(ClockSynchThread));
+
+        /// <summary> Holds the clock syncher for the synch thread. </summary>
+        private ClockSynchronizer clockSyncher;
+
+        /// <summary> Holds the throttle to limit the synch rate. </summary>
+        private Throttle throttle;
+
+        /// <summary> Flag to indicate that the periodic clock syncher should keep running. </summary>
+        bool doSynch = true;
+
+        /// <summary>
+        /// Creates a clock synchronizer thread from a clock synchronizer and a throttle.
+        /// </summary>
+        /// <param name="syncher">  The clock synchronizer. </param>
+        /// <param name="throttle"> The throttle. </param>
+        public ClockSynchThread(ClockSynchronizer syncher, Throttle throttle)
+        {
+            this.clockSyncher = syncher;
+            this.throttle = throttle;
+        }
+
+        /// <summary> Terminates the synchronization thread. </summary>
+        public void terminate()
+        {
+            doSynch = false;
+        }
+
+        /// <summary> Continually updates the clock, until <see cref="#terminate()"/> is called. </summary>
+        public void run()
+        {
+            while (doSynch)
+            {
+                // Perform a clock clockSynch.
+                try
+                {
+                    // Wait controlled by the throttle before doing the next synch.
+                    throttle.throttle();
+
+                    clockSyncher.synch();
+                    log.debug("Clock synched, delta = " + clockSyncher.getDelta() + ", epsilon = " + clockSyncher.getEpsilon()
+                              + ".");
+                }
+                // Terminate the synch thread if the synchronization cannot be achieved.
+                catch (ClockSynchFailureException e)
+                {
+                    log.debug("Cannot synchronize the clock (reference service may be down). Terminating the synch thread.");
+                    doSynch = false;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the clock synchronizer that is kept continually up to date.
+        /// </summary>
+        /// <return> The clock synchronizer that is kept continually up to date. </return>
+        public ClockSynchronizer getClockSyncher()
+        {
+            return clockSyncher;
+        }
+
+        /// <summary>
+        /// Supplies a shutdown hook, that terminates the synching thread.
+        /// </summary>
+        /// <return> The shut down hook. </return>
+        public Thread getShutdownHook()
+        {
+            return new Thread(new Runnable()
+                {
+                    public void run()
+                    {
+                        doSynch = false;
+                    }
+                });
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+
+    /// <summary>
+    /// LocalClockSynchronizer is a fake <see cref="ClockSynchronizer"/> that simply calls System.nanoTime(). It exists so that
+    /// the same tests can be run distributed or locally, taking timings against the ClockSynchronizer interface without
+    /// being aware of how they are being run.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Supply the local clock with no delta.
+    /// </table>
+    /// </summary>
+    public class LocalClockSynchronizer : ClockSynchronizer
+    {
+        /// <summary>
+        /// The slave side should call this to copute a clock delta with the reference.
+        /// </summary>
+        /// <exception cref="Apache.Qpid.Integration.Tests.framework.clocksynch.ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+        public void synch() throws ClockSynchFailureException
+        { }
+
+        /// <summary>
+        /// Gets the clock delta in nano seconds.
+        /// </summary>
+        /// <return> The clock delta in nano seconds. </return>
+        public long getDelta()
+        {
+            return 0L;
+        }
+
+        /// <summary>
+        /// Gets an estimate of the clock error in nan seconds.
+        /// </summary>
+        /// <return> An estimate of the clock error in nan seconds. </return>
+        public long getEpsilon()
+        {
+            return 0L;
+        }
+
+        /// <summary>
+        /// Gets the local clock time with any computed delta added in.
+        /// </summary>
+        /// <return> The local clock time with any computed delta added in. </return>
+        public long nanoTime()
+        {
+            return System.nanoTime();
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+
+using java.io.IOException;
+using java.net.*;
+using java.nio.ByteBuffer;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+    /// <summary>
+    /// UDPClockReference supplies a refernce clock signal (generated from System.nanoTime()).
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Supply a reference clock signal.
+    /// </table>
+    /// </summary>
+    ///
+    /// <remarks> Port hard coded. Make configurable.</remarks>
+    ///
+    /// <remarks> Errors rethrown as runtimes, or silently terminate the service. Could add better error handling if needed.</remarks>
+    public class UDPClockReference : Runnable, ShutdownHookable
+    {
+        /// <summary> Used for debugging. </summary>
+        // private static ILog log = LogManager.GetLogger(typeof(UDPClockReference));
+
+        /// <summary> Defines the timeout to use when polling the socket for time requests. </summary>
+        private static final int TIMEOUT = 200;
+
+        /// <summary> Defines the port to run the clock reference on. </summary>
+        public static final int REFERENCE_PORT = 4444;
+
+        /// <summary> Holds the socket to receive clock reference requests on. </summary>
+        protected DatagramSocket socket = null;
+
+        /// <summary> Flag used to indicate that the time server should keep running. Set to false to terminate. </summary>
+        protected bool publish = true;
+
+        /// <summary> Creates a clock reference service on the standard port. </summary>
+        public UDPClockReference()
+        {
+            try
+            {
+                socket = new DatagramSocket(REFERENCE_PORT);
+                socket.setSoTimeout(TIMEOUT);
+            }
+            catch (SocketException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /// <summary>
+        /// Implements the run loop for this reference time server. This waits for incoming time requests, and replies to
+        /// any, with a message with the local time stamp in it. Periodically (controlled by <see cref="#TIMEOUT"/>), the run
+        /// loop will check if the <see cref="#publish"/> flag has been cleared, and terminate the reference time service if so.
+        /// </summary>
+        public void run()
+        {
+            byte[] buf = new byte[256];
+            ByteBuffer bbuf = ByteBuffer.wrap(buf);
+
+            while (publish)
+            {
+                try
+                {
+                    // Wait for a reference time request.
+                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
+                    bool timedOut = false;
+
+                    try
+                    {
+                        socket.receive(packet);
+                    }
+                    catch (SocketTimeoutException e)
+                    {
+                        timedOut = true;
+                    }
+
+                    if (!timedOut)
+                    {
+                        // Work out from the received packet, where to reply to.
+                        InetAddress address = packet.getAddress();
+                        int port = packet.getPort();
+
+                        // Respond to the time request by sending back the local clock as the reference time.
+                        bbuf.putLong(System.nanoTime());
+                        bbuf.flip();
+                        packet = new DatagramPacket(bbuf.array(), bbuf.capacity(), address, port);
+
+                        socket.send(packet);
+                    }
+                }
+                catch (IOException e)
+                {
+                    publish = false;
+                }
+            }
+
+            socket.close();
+        }
+
+        /// <summary>
+        /// Supplies a shutdown hook.
+        /// </summary>
+        /// <return> The shut down hook. </return>
+        public Thread getShutdownHook()
+        {
+            return new Thread(new Runnable()
+                {
+                    public void run()
+                    {
+                        publish = false;
+                    }
+                });
+        }
+
+        /// <summary>
+        /// For testing purposes. Runs a reference clock on the default port.
+        /// </summary>
+        /// <param name="args"> None. </param>
+        public static void main(String[] args)
+        {
+            try
+            {
+                // Create the clock reference service.
+                UDPClockReference clock = new UDPClockReference();
+
+                // Set up a shutdown hook for it.
+                Runtime.getRuntime().addShutdownHook(clock.getShutdownHook());
+
+                // Start the service.
+                clock.run();
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+                System.exit(1);
+            }
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.util.CommandLineParser;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using java.io.IOException;
+using java.net.*;
+using java.nio.ByteBuffer;
+using java.util.Arrays;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+    /// <summary>
+    /// UDPClockSynchronizer is a <see cref="ClockSynchronizer"/> that sends pings as UDP datagrams, and uses the following simple
+    /// algorithm to perform clock synchronization:
+    ///
+    /// <ol>
+    /// <li>Slave initiates synchronization with a Reference clock.</li>
+    /// <li>Slave stamps current local time on a "time request" message and sends to the Reference.</li>
+    /// <li>Upon receipt by Reference, Reference stamps Reference-time and returns.</li>
+    /// <li>Upon receipt by Slave, Slave subtracts current time from sent time and divides by two to compute latency. It
+    ///     subtracts current time from Reference time to determine Slave-Reference time delta and adds in the
+    ///     half-latency to get the correct clock delta.</li>
+    /// <li>The first result is immediately used to update the clock since it will get the local clock into at least
+    ///     the right ballpark.</li>
+    /// <li>The Slave repeats steps 2 through 4, 15 more times.</li>
+    /// <li>The results of the packet receipts are accumulated and sorted in lowest-latency to highest-latency order. The
+    ///     median latency is determined by picking the mid-point sample from this ordered list.</li>
+    /// <li>All samples outside 1 standard-deviation from the median are discarded and the remaining samples
+    ///     are averaged using an arithmetic mean.</li>
+    /// </ol>
+    ///
+    /// <p/>The use of UDP datagrams, instead of TCP based communication eliminates the hidden delays that TCP can introduce,
+    /// as it can transparently re-order or re-send packets, or introduce delays as packets are naggled.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Trigger a clock synchronziation.
+    /// <tr><td> Compute a clock delta to apply to the local clock.
+    /// <tr><td> Estimate the error in the synchronzation.
+    /// </table>
+    /// </summary>
+    public class UDPClockSynchronizer : ClockSynchronizer
+    {
+        /// <summary> Used for debugging. </summary>
+        // private static ILog log = LogManager.GetLogger(typeof(UDPClockSynchronizer));
+
+        /// <summary> Defines the timeout to use when waiting for responses to time requests. </summary>
+        private static final int TIMEOUT = 50;
+
+        /// <summary> The clock delta. </summary>
+        private long delta = 0L;
+
+        /// <summary> Holds an estimate of the clock error relative to the reference clock. </summary>
+        private long epsilon = 0L;
+
+        /// <summary> Holds the address of the reference clock. </summary>
+        private InetAddress referenceAddress;
+
+        /// <summary> Holds the socket to communicate with the reference service over. </summary>
+        private DatagramSocket socket;
+
+        /// <summary> Used to control the shutdown in the main test loop. </summary>
+        private static bool doSynch = true;
+
+        /// <summary>
+        /// Creates a clock synchronizer against the specified address for the reference.
+        /// </summary>
+        /// <param name="address"> The address of the reference service. </param>
+        public UDPClockSynchronizer(string address)
+        {
+            try
+            {
+                referenceAddress = InetAddress.getByName(address);
+            }
+            catch (UnknownHostException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /// <summary>
+        /// The slave side should call this to compute a clock delta with the reference.
+        /// </summary>
+        /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference
+        /// time service. </exception>
+        public void synch() throws ClockSynchFailureException
+        {
+            try
+            {
+                socket = new DatagramSocket();
+                socket.setSoTimeout(TIMEOUT);
+
+                // Synchronize on a single ping, to get the clock into the right ball-park.
+                synch(1);
+
+                // Synchronize on 15 pings.
+                synch(15);
+
+                // And again, for greater accuracy, on 31.
+                synch(31);
+
+                socket.close();
+            }
+            catch (SocketException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /// <summary>
+        /// Updates the synchronization delta by performing the specified number of reference clock requests.
+        /// </summary>
+        /// <param name="n"> The number of reference clock request cycles to perform. </param>
+        ///
+        /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference 
+        ///                                               time service. </exception>
+        protected void synch(int n) throws ClockSynchFailureException
+        {
+            // log.debug("protected void synch(int n = " + n + "): called");
+
+            // Create an array of deltas by performing n reference pings.
+            long[] delta = new long[n];
+
+            for (int i = 0; i < n; i++)
+            {
+                delta[i] = ping();
+            }
+
+            // Reject any deltas that are larger than 1 s.d. above the median.
+            long median = median(delta);
+            long sd = standardDeviation(delta);
+
+            // log.debug("median = " + median);
+            // log.debug("sd = " + sd);
+
+            long[] tempDeltas = new long[n];
+            int count = 0;
+
+            for (int i = 0; i < n; i++)
+            {
+                if ((delta[i] <= (median + sd)) && (delta[i] >= (median - sd)))
+                {
+                    tempDeltas[count] = delta[i];
+                    count++;
+                }
+                else
+                {
+                    // log.debug("Rejected: " + delta[i]);
+                }
+            }
+
+            System.arraycopy(tempDeltas, 0, delta, 0, count);
+
+            // Estimate the delta as the mean of the remaining deltas.
+            this.delta += mean(delta);
+
+            // Estimate the error as the standard deviation of the remaining deltas.
+            this.epsilon = standardDeviation(delta);
+
+            // log.debug("this.delta = " + this.delta);
+            // log.debug("this.epsilon = " + this.epsilon);
+        }
+
+        /// <summary>
+        /// Performs a single reference clock request cycle and returns the estimated delta relative to the local clock.
+        /// This is computed as the half-latency of the requst cycle, plus the reference clock, minus the local clock.
+        /// </summary>
+        /// <return> The estimated clock delta. </return>
+        ///
+        /// <exception cref="ClockSynchFailureException"> If the reference service is not responding. </exception>
+        protected long ping() throws ClockSynchFailureException
+        {
+            // log.debug("protected long ping(): called");
+
+            try
+            {
+                byte[] buf = new byte[256];
+
+                bool timedOut = false;
+                long start = 0L;
+                long refTime = 0L;
+                long localTime = 0L;
+                long latency = 0L;
+                int failCount = 0;
+
+                // Keep trying the ping until it gets a response, or 10 tries in a row all time out.
+                do
+                {
+                    // Start timing the request latency.
+                    start = nanoTime();
+
+                    // Get the reference time.
+                    DatagramPacket packet =
+                        new DatagramPacket(buf, buf.length, referenceAddress, UDPClockReference.REFERENCE_PORT);
+                    socket.send(packet);
+                    packet = new DatagramPacket(buf, buf.length);
+
+                    timedOut = false;
+
+                    try
+                    {
+                        socket.receive(packet);
+                    }
+                    catch (SocketTimeoutException e)
+                    {
+                        timedOut = true;
+                        failCount++;
+
+                        continue;
+                    }
+
+                    ByteBuffer bbuf = ByteBuffer.wrap(packet.getData());
+                    refTime = bbuf.getLong();
+
+                    // Stop timing the request latency.
+                    localTime = nanoTime();
+                    latency = localTime - start;
+
+                    // log.debug("refTime = " + refTime);
+                    // log.debug("localTime = " + localTime);
+                    // log.debug("start = " + start);
+                    // log.debug("latency = " + latency);
+                    // log.debug("delta = " + ((latency / 2) + (refTime - localTime)));
+
+                }
+                while (timedOut && (failCount < 10));
+
+                // Fail completely if the fail count is too high.
+                if (failCount >= 10)
+                {
+                    throw new ClockSynchFailureException("Clock reference not responding.", null);
+                }
+
+                // Estimate delta as (ref clock + half-latency) - local clock.
+                return (latency / 2) + (refTime - localTime);
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /// <summary>
+        /// Gets the clock delta in nano seconds.
+        /// </summary>
+        /// <return> The clock delta in nano seconds. </return>
+        public long getDelta()
+        {
+            return delta;
+        }
+
+        /// <summary>
+        /// Gets an estimate of the clock error in nan seconds.
+        /// </summary>
+        /// <return> An estimate of the clock error in nan seconds. </return>
+        public long getEpsilon()
+        {
+            return epsilon;
+        }
+
+        /// <summary>
+        /// Gets the local clock time with any computed delta added in.
+        /// </summary>
+        /// <return> The local clock time with any computed delta added in. </return>
+        public long nanoTime()
+        {
+            return System.nanoTime() + delta;
+        }
+
+        /// <summary>
+        /// Computes the median of a series of values.
+        /// </summary>
+        /// <param name="values"> The values. </param>
+        ///
+        /// <return> The median. </return>
+        public static long median(long[] values)
+        {
+            // log.debug("public static long median(long[] values = " + Arrays.ToString(values) + "): called");
+
+            long median;
+
+            // Order the list of values.
+            long[] orderedValues = new long[values.length];
+            System.arraycopy(values, 0, orderedValues, 0, values.length);
+            Arrays.sort(orderedValues);
+
+            // Check if the median is computed from a pair of middle value.
+            if ((orderedValues.length % 2) == 0)
+            {
+                int middle = orderedValues.length / 2;
+
+                median = (orderedValues[middle] + orderedValues[middle - 1]) / 2;
+            }
+            // The median is computed from a single middle value.
+            else
+            {
+                median = orderedValues[orderedValues.length / 2];
+            }
+
+            // log.debug("median = " + median);
+
+            return median;
+        }
+
+        /// <summary>
+        /// Computes the mean of a series of values.
+        /// </summary>
+        /// <param name="values"> The values. </param>
+        ///
+        /// <return> The mean. </return>
+        public static long mean(long[] values)
+        {
+            // log.debug("public static long mean(long[] values = " + Arrays.ToString(values) + "): called");
+
+            long total = 0L;
+
+            for (long value : values)
+            {
+                total += value;
+            }
+
+            long mean = total / values.length;
+
+            // log.debug("mean = " + mean);
+
+            return mean;
+        }
+
+        /// <summary>
+        /// Computes the variance of series of values.
+        /// </summary>
+        /// <param name="values"> The values. </param>
+        ///
+        /// <return> The variance of the values. </return>
+        public static long variance(long[] values)
+        {
+            // log.debug("public static long variance(long[] values = " + Arrays.ToString(values) + "): called");
+
+            long mean = mean(values);
+
+            long totalVariance = 0;
+
+            for (long value : values)
+            {
+                long diff = (value - mean);
+                totalVariance += diff/// diff;
+                    }
+
+            long variance = totalVariance / values.length;
+
+            // log.debug("variance = " + variance);
+
+            return variance;
+        }
+
+        /// <summary>
+        /// Computes the standard deviation of a series of values.
+        /// </summary>
+        /// <param name="values"> The values. </param>
+        ///
+        /// <return> The standard deviation. </return>
+        public static long standardDeviation(long[] values)
+        {
+            // log.debug("public static long standardDeviation(long[] values = " + Arrays.ToString(values) + "): called");
+
+            long sd = Double.valueOf(Math.sqrt(variance(values))).longValue();
+
+            // log.debug("sd = " + sd);
+
+            return sd;
+        }
+
+        /// <summary>
+        /// For testing purposes. Supply address of reference clock as arg 1.
+        /// </summary>
+        /// <param name="args"> Address of reference clock as arg 1. </param>
+        public static void main(String[] args)
+        {
+            ParsedProperties options =
+                new ParsedProperties(CommandLineParser.processCommandLine(args,
+                                                                          new CommandLineParser(
+                                                                                                new String[][]
+                                                                                                {
+                                                                                                    { "1", "Address of clock reference service.", "address", "true" }
+                                                                                                }), System.getProperties()));
+
+            string address = options.getProperty("1");
+
+            // Create a clock synchronizer.
+            UDPClockSynchronizer clockSyncher = new UDPClockSynchronizer(address);
+
+            // Set up a shutdown hook for it.
+            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
+                {
+                    public void run()
+                    {
+                        doSynch = false;
+                    }
+                }));
+
+            // Repeat the clock synching until the user kills the progam.
+            while (doSynch)
+            {
+                // Perform a clock clockSynch.
+                try
+                {
+                    clockSyncher.synch();
+
+                    // Print out the clock delta and estimate of the error.
+                    System.out.println("Delta = " + clockSyncher.getDelta());
+                    System.out.println("Epsilon = " + clockSyncher.getEpsilon());
+
+                    try
+                    {
+                        Thread.sleep(250);
+                    }
+                    catch (InterruptedException e)
+                    {
+                        // Restore the interrupted status and terminate the loop.
+                        Thread.currentThread().interrupt();
+                        doSynch = false;
+                    }
+                }
+                // Terminate if the reference time service is unavailable.
+                catch (ClockSynchFailureException e)
+                {
+                    doSynch = false;
+                }
+            }
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.TimingController;
+using uk.co.thebadgerset.junit.extensions.TimingControllerAware;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Destination;
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.Session;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+    /// <summary>
+    /// DistributedCircuitImpl is a distributed implementation of the test <see cref="Circuit"/>. Many publishers and receivers
+    /// accross multiple machines may be combined to form a single test circuit. The test circuit extracts reports from
+    /// all of its publishers and receivers, and applies its assertions to these reports.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+    /// <tr><td> Start the circuit running.
+    /// <tr><td> Close the circuit down.
+    /// <tr><td> Take a reading of the circuits state.
+    /// <tr><td> Apply assertions against the circuits state.
+    /// <tr><td> Send test messages over the circuit.
+    /// <tr><td> Perform the default test procedue on the circuit.
+    /// </table>
+    /// </summary>
+    ///
+    /// <remarks> There is a short pause after receiving sender reports before asking for receiver reports, because receivers may
+    ///       not have finished receiving all their test messages before the report request arrives. This is going to be a
+    ///       problem for taking test timings and needs to be eliminiated. Suggested solution: have receiver send back reports
+    ///       asynchronously, on test batch size boundaries, and do so automatically rather than having to have the report
+    ///       request sent to them. Number each test run, or otherwise uniquely identify it, when a receiver does not get
+    ///       any more messages on a test run for more than a timeout, it can assume the test is complete and send a final
+    ///       report. On the coordinator end a future will need to be created to wait for all final reports to come in, and
+    ///       to register results and timings for the test. This must work in such a way that a new test cycle can be started
+    ///       without waiting for the results of the old one to come in.</remarks>
+    ///
+    /// <remarks> Add in setting of timing controller, from timing aware test cases.</remarks>
+    public class DistributedCircuitImpl : Circuit, TimingControllerAware
+    {
+        /// <summary> Used for debugging purposes. </summary>
+        private static ILog log = LogManager.GetLogger(typeof(DistributedCircuitImpl));
+
+        /// <summary> Holds the conversation factory over which to coordinate the test. </summary>
+        protected ConversationFactory conversationFactory;
+
+        /// <summary> Holds the controlSession over which to hold the control conversation. </summary>
+        protected Session controlSession;
+
+        /// <summary> Holds the sender nodes in the test circuit. </summary>
+        protected IList<TestClientDetails> senders;
+
+        /// <summary> Holds the receiver nodes in the test circuit. </summary>
+        protected IList<TestClientDetails> receivers;
+
+        /// <summary> Holds the sender control conversations. </summary>
+        protected ConversationFactory.Conversation[] senderConversation;
+
+        /// <summary> Holds the receiver control conversations. </summary>
+        protected ConversationFactory.Conversation[] receiverConversation;
+
+        /// <summary> Holds the control topics for the senders in the test circuit. </summary>
+        protected Destination[] senderControlTopic;
+
+        /// <summary> Holds the control topics for the receivers in the test circuit. </summary>
+        protected Destination[] receiverControlTopic;
+
+        /// <summary> Holds the number of messages to send per test run. </summary>
+        protected int numMessages;
+
+        /// <summary>
+        /// Holds the timing controller for the circuit. This is used to log test times asynchronously, when reciever nodes
+        /// return their reports after senders have completed a test case.
+        TimingController timingController;
+
+        /// <summary>
+        /// Creates a distributed test circuit on the specified senders and receivers.
+        /// </summary>
+        /// <param name="session">              The controlSession for all control conversations. </param>
+        /// <param name="senders">              The senders. </param>
+        /// <param name="receivers">            The receivers. </param>
+        /// <param name="senderConversation">   A control conversation with the senders. </param>
+        /// <param name="receiverConversation"> A control conversation with the receivers. </param>
+        /// <param name="senderControlTopic">   The senders control topic. </param>
+        /// <param name="receiverControlTopic"> The receivers control topic. </param>
+        protected DistributedCircuitImpl(Session session, IList<TestClientDetails> senders, List<TestClientDetails> receivers,
+                                         ConversationFactory.Conversation[] senderConversation, ConversationFactory.Conversation[] receiverConversation,
+                                         Destination[] senderControlTopic, Destination[] receiverControlTopic)
+        {
+            this.controlSession = session;
+            this.senders = senders;
+            this.receivers = receivers;
+            this.senderConversation = senderConversation;
+            this.receiverConversation = receiverConversation;
+            this.senderControlTopic = senderControlTopic;
+            this.receiverControlTopic = receiverControlTopic;
+        }
+
+        /// <summary>
+        /// Creates a distributed test circuit from the specified test parameters, on the senders and receivers
+        /// given.
+        /// </summary>
+        /// <param name="testProps">           The test parameters. </param>
+        /// <param name="senders">             The sender ends in the test circuit. </param>
+        /// <param name="receivers">           The receiver ends in the test circuit. </param>
+        /// <param name="conversationFactory"> A conversation factory for creating the control conversations with senders and receivers. </param>
+        ///
+        /// <return> A connected and ready to start, test circuit. </return>
+        public static Circuit createCircuit(ParsedProperties testProps, IList<TestClientDetails> senders,
+                                            IList<TestClientDetails> receivers, ConversationFactory conversationFactory)
+        {
+            log.debug("public static Circuit createCircuit(ParsedProperties testProps, IList<TestClientDetails> senders, "
+                      + " IList<TestClientDetails> receivers, ConversationFactory conversationFactory)");
+
+            try
+            {
+                Session session = conversationFactory.getSession();
+
+                // Create control conversations with each of the senders.
+                ConversationFactory.Conversation[] senderConversation = new ConversationFactory.Conversation[senders.size()];
+                Destination[] senderControlTopic = new Destination[senders.size()];
+
+                for (int i = 0; i < senders.size(); i++)
+                {
+                    TestClientDetails sender = senders.get(i);
+
+                    senderControlTopic[i] = session.createTopic(sender.privateControlKey);
+                    senderConversation[i] = conversationFactory.startConversation();
+                }
+
+                log.debug("Sender conversations created.");
+
+                // Create control conversations with each of the receivers.
+                ConversationFactory.Conversation[] receiverConversation = new ConversationFactory.Conversation[receivers.size()];
+                Destination[] receiverControlTopic = new Destination[receivers.size()];
+
+                for (int i = 0; i < receivers.size(); i++)
+                {
+                    TestClientDetails receiver = receivers.get(i);
+
+                    receiverControlTopic[i] = session.createTopic(receiver.privateControlKey);
+                    receiverConversation[i] = conversationFactory.startConversation();
+                }
+
+                log.debug("Receiver conversations created.");
+
+                // Assign the sender role to each of the sending test clients.
+                for (int i = 0; i < senders.size(); i++)
+                {
+                    TestClientDetails sender = senders.get(i);
+
+                    Message assignSender = conversationFactory.getSession().createMessage();
+                    TestUtils.setPropertiesOnMessage(assignSender, testProps);
+                    assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+                    assignSender.setStringProperty("ROLE", "SENDER");
+
+                    senderConversation[i].send(senderControlTopic[i], assignSender);
+                }
+
+                log.debug("Sender role assignments sent.");
+
+                // Assign the receivers role to each of the receiving test clients.
+                for (int i = 0; i < receivers.size(); i++)
+                {
+                    TestClientDetails receiver = receivers.get(i);
+
+                    Message assignReceiver = session.createMessage();
+                    TestUtils.setPropertiesOnMessage(assignReceiver, testProps);
+                    assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+                    assignReceiver.setStringProperty("ROLE", "RECEIVER");
+
+                    receiverConversation[i].send(receiverControlTopic[i], assignReceiver);
+                }
+
+                log.debug("Receiver role assignments sent.");
+
+                // Wait for the senders and receivers to confirm their roles.
+                for (int i = 0; i < senders.size(); i++)
+                {
+                    senderConversation[i].receive();
+                }
+
+                log.debug("Got all sender role confirmations");
+
+                for (int i = 0; i < receivers.size(); i++)
+                {
+                    receiverConversation[i].receive();
+                }
+
+                log.debug("Got all receiver role confirmations");
+
+                // Package everything up as a circuit.
+                return new DistributedCircuitImpl(session, senders, receivers, senderConversation, receiverConversation,
+                                                  senderControlTopic, receiverControlTopic);
+            }
+            catch (JMSException e)
+            {
+                throw new RuntimeException("JMSException not handled.");
+            }
+        }
+
+        /// <summary>
+        /// Used by tests cases that can supply a <see cref="uk.co.thebadgerset.junit.extensions.TimingController"/> to set the
+        /// controller on an aware test.
+        /// </summary>
+        /// <param name="controller"> The timing controller. </param>
+        public void setTimingController(TimingController controller)
+        {
+            this.timingController = controller;
+        }
+
+        /// <summary>
+        /// Gets the interface on the publishing end of the circuit.
+        /// </summary>
+        /// <return> The publishing end of the circuit. </return>
+        public Publisher getPublisher()
+        {
+            throw new RuntimeException("Not Implemented.");
+        }
+
+        /// <summary>
+        /// Gets the interface on the receiving end of the circuit.
+        /// </summary>
+        /// <return> The receiving end of the circuit. </return>
+        public Receiver getReceiver()
+        {
+            throw new RuntimeException("Not Implemented.");
+        }
+
+        /// <summary>
+        /// Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+        public void start()
+        {
+            log.debug("public void start(): called");
+
+            try
+            {
+                // Start the test on each of the senders.
+                Message start = controlSession.createMessage();
+                start.setStringProperty("CONTROL_TYPE", "START");
+                start.setIntProperty("MESSAGE_COUNT", numMessages);
+
+                for (int i = 0; i < senders.size(); i++)
+                {
+                    senderConversation[i].send(senderControlTopic[i], start);
+                }
+
+                log.debug("All senders told to start their tests.");
+            }
+            catch (JMSException e)
+            {
+                throw new RuntimeException("Unhandled JMSException.", e);
+            }
+        }
+
+        /// <summary>
+        /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+        /// into a report, against which assertions may be checked.
+        /// </summary>
+        /// <remarks> Replace the asynch receiver report thread with a choice of direct or asynch executor, so that asynch
+        ///       or synch logging of test timings is optional. Also need to provide an onMessage method that is capable
+        ///       of receiving timing reports that receivers will generate during an ongoing test, on the test sample
+        ///       size boundaries. The message timing logging code should be factored out as a common method that can
+        ///       be called in response to the final report responses, or the onMessage method. Another alternative is
+        ///       to abandon the final report request altogether and just use the onMessage method? I think the two
+        ///       differ though, as the final report is used to apply assertions, and the ongoing report is just for
+        ///       periodic timing results... In which case, maybe there needs to be a way for the onMessage method
+        ///       to process just some of the incoming messages, and forward the rest on to the conversion helper, as
+        ///       a sort of pre-conversation helper filter? Make conversation expose its onMessage method (it should
+        ///       already) and allow another delivery thread to filter the incoming messages to the conversation.</remarks>
+        public void check()
+        {
+            log.debug("public void check(): called");
+
+            try
+            {
+                // Wait for all the test senders to return their reports.
+                for (int i = 0; i < senders.size(); i++)
+                {
+                    Message senderReport = senderConversation[i].receive();
+                    log.debug("Sender " + senderReport.getStringProperty("CLIENT_NAME") + " reports message count: "
+                              + senderReport.getIntProperty("MESSAGE_COUNT"));
+                    log.debug("Sender " + senderReport.getStringProperty("CLIENT_NAME") + " reports message time: "
+                              + senderReport.getLongProperty("TEST_TIME"));
+                }
+
+                log.debug("Got all sender test reports.");
+
+                // Apply sender assertions to pass/fail the tests.
+
+                // Inject a short pause to give the receivers time to finish receiving their test messages.
+                TestUtils.pause(500);
+
+                // Ask the receivers for their reports.
+                Message statusRequest = controlSession.createMessage();
+                statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+                for (int i = 0; i < receivers.size(); i++)
+                {
+                    receiverConversation[i].send(receiverControlTopic[i], statusRequest);
+                }
+
+                log.debug("All receiver test reports requested.");
+
+                // Wait for all receiver reports to come in, but do so asynchronously.
+                Runnable gatherAllReceiverReports =
+                    new Runnable()
+                    {
+                        public void run()
+                        {
+                            try
+                            {
+                                // Wait for all the receivers to send their reports.
+                                for (int i = 0; i < receivers.size(); i++)
+                                {
+                                    Message receiverReport = receiverConversation[i].receive();
+
+                                    string clientName = receiverReport.getStringProperty("CLIENT_NAME");
+                                    int messageCount = receiverReport.getIntProperty("MESSAGE_COUNT");
+                                    long testTime = receiverReport.getLongProperty("TEST_TIME");
+
+                                    log.debug("Receiver " + clientName + " reports message count: " + messageCount);
+                                    log.debug("Receiver " + receiverReport.getStringProperty("CLIENT_NAME")
+                                              + " reports message time: " + testTime);
+
+                                    // Apply receiver assertions to pass/fail the tests.
+
+                                    // Log the test timings on the asynchronous test timing controller.
+                                    /*try
+                                      {
+                                      timingController.completeTest(true, messageCount, testTime);
+                                      }
+                                      // The timing controll can throw InterruptedException is the current test is to be
+                                      // interrupted.
+                                      catch (InterruptedException e)
+                                      {
+                                      e.printStackTrace();
+                                      }*/
+                                }
+
+                                log.debug("All receiver test reports received.");
+                            }
+                            catch (JMSException e)
+                            {
+                                throw new RuntimeException(e);
+                            }
+                        }
+                    };
+
+                Thread receiverReportsThread = new Thread(gatherAllReceiverReports);
+                receiverReportsThread.start();
+
+                // return new Message[] { senderReport, receiverReport };
+
+            }
+            catch (JMSException e)
+            {
+                throw new RuntimeException("Unhandled JMSException.", e);
+            }
+        }
+
+        /// <summary> Closes the circuit. All associated resources are closed. </summary>
+        public void close()
+        {
+            log.debug("public void close(): called");
+
+            // End the current test on all senders and receivers.
+        }
+
+        /// <summary>
+        /// Applies a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+        /// this, to ensure that the circuit has gathered its state into a report to assert against.
+        /// </summary>
+        /// <param name="assertions"> The list of assertions to apply. </param>
+        ///
+        /// <return> Any assertions that failed. </return>
+        public IList<Assertion> applyAssertions(List<Assertion> assertions)
+        {
+            log.debug("public IList<Assertion> applyAssertions(List<Assertion> assertions = " + assertions + "): called");
+
+            IList<Assertion> failures = new LinkedList<Assertion>();
+
+            for (Assertion assertion : assertions)
+            {
+                if (!assertion.apply())
+                {
+                    failures.add(assertion);
+                }
+            }
+
+            return failures;
+        }
+
+        /// <summary>
+        /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+        /// </summary>
+        /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+        /// <param name="assertions">  The list of assertions to apply. </param>
+        ///
+        /// <return> Any assertions that failed. </return>
+        ///
+        /// <remarks> From check onwards needs to be handled as a future. The future must call back onto the test case to
+        ///       report results asynchronously.</remarks>
+        public IList<Assertion> test(int numMessages, List<Assertion> assertions)
+        {
+            log.debug("public IList<Assertion> test(int numMessages = " + numMessages + ", List<Assertion> assertions = "
+                      + assertions + "): called");
+
+            // Keep the number of messages to send per test run, where the send method can reference it.
+            this.numMessages = numMessages;
+
+            // Start the test running on all sender circuit ends.
+            start();
+
+            // Request status reports to be handed in.
+            check();
+
+            // Assert conditions on the publishing end of the circuit.
+            // Assert conditions on the receiving end of the circuit.
+            IList<Assertion> failures = applyAssertions(assertions);
+
+            // Close the circuit ending the current test case.
+            close();
+
+            // Pass with no failed assertions or fail with a list of failed assertions.
+            return failures;
+        }
+    }
+}
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Publisher;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+    /// <summary>
+    /// DistributedPublisherImpl represents the status of the publishing side of a test circuit. Its main purpose is to
+    /// provide assertions that can be applied to verify the behaviour of a non-local publisher.
+    ///
+    /// <p/><table id="crc"><caption>CRC Card</caption>
+    /// <tr><th> Responsibilities <th> Collaborations
+    /// <tr><td> Provide assertion that the publishers received no exceptions.
+    /// <tr><td> Provide assertion that the publishers received a no consumers error code on every message.
+    /// <tr><td> Provide assertion that the publishers received a no route error code on every message.
+    /// </table>
+    /// </summary>
+    public class DistributedPublisherImpl : Publisher
+    {
+        /// <summary>
+        /// Provides an assertion that the publisher encountered no exceptions.
+        /// </summary>
+        /// <param name="testProps"> The test configuration properties. </param>
+        /// <return> An assertion that the publisher encountered no exceptions. </return>
+        public Assertion noExceptionsAssertion(ParsedProperties testProps)
+        {
+            throw new RuntimeException("Not implemented.");
+        }
+
+        /// <summary>
+        /// Provides an assertion that the publisher got a no consumers exception on every message.
+        /// </summary>
+        /// <return> An assertion that the publisher got a no consumers exception on every message. </return>
+        public Assertion noConsumersAssertion()
+        {
+            throw new RuntimeException("Not implemented.");
+        }
+
+        /// <summary>
+        /// Provides an assertion that the publisher got a no rout exception on every message.
+        /// </summary>
+        /// <return> An assertion that the publisher got a no rout exception on every message. </return>
+        public Assertion noRouteAssertion()
+        {
+            throw new RuntimeException("Not implemented.");
+        }
+
+        /// <summary>

[... 5804 lines stripped ...]


Mime
View raw message