@Test
 public void testPublishAndSubscribe() throws Exception {
   // add a null subscriber
   mToken.subscribe(null);
   // publish null
   mToken.publishAndWait(null);
   // publish no subscribers
   mToken.publishAndWait(this);
   // create a subscriber
   MockSubscriber s1 = new MockSubscriber();
   // subscribe
   mToken.subscribe(s1);
   // publish to subscriber
   mToken.publishAndWait(this);
   // subscriber got publication
   verifySubscribers(new MockSubscriber[] {s1}, new MockSubscriber[] {}, this);
   // add second subscriber
   MockSubscriber s2 = new MockSubscriber();
   mToken.subscribe(s2);
   // publish a different object this time
   mToken.publishAndWait(this.getClass());
   // make sure both subscribers got it
   verifySubscribers(new MockSubscriber[] {s1, s2}, new MockSubscriber[] {}, this.getClass());
   // add second subscriber again
   mToken.subscribe(s2);
   // notify with a different type of object
   mToken.publishAndWait(mTokenSpec);
   // make sure subscribers were notified (make sure s2 was notified only once)
   verifySubscribers(new MockSubscriber[] {s1, s2}, new MockSubscriber[] {}, mTokenSpec);
   // throw in some unsubscribes
   mToken.unsubscribe(null);
   MockSubscriber s3 = new MockSubscriber();
   mToken.unsubscribe(s3);
   // publish again
   mToken.publishAndWait(dataRequest);
   verifySubscribers(new MockSubscriber[] {s1, s2}, new MockSubscriber[] {s3}, dataRequest);
   // remove existing subscribers
   mToken.unsubscribe(s1);
   mToken.unsubscribe(s2);
   // publish again
   mToken.publishAndWait(mCredentials);
   // nobody should get anything
   verifySubscribers(new MockSubscriber[] {}, new MockSubscriber[] {s1, s2, s3}, mCredentials);
   // repeat a few tests with the list subscribe
   mToken.subscribeAll((ISubscriber[]) null);
   // nobody is subscribed
   mToken.publishAndWait(s1);
   verifySubscribers(new MockSubscriber[] {}, new MockSubscriber[] {s1, s2, s3}, s1);
   List<ISubscriber> subscribers = new ArrayList<ISubscriber>();
   // still, nobody is subscribed
   mToken.subscribeAll(subscribers.toArray(new ISubscriber[subscribers.size()]));
   mToken.publishAndWait(s2);
   verifySubscribers(new MockSubscriber[] {}, new MockSubscriber[] {s1, s2, s3}, s2);
   // add a subscriber
   subscribers.add(s1);
   mToken.subscribeAll(subscribers.toArray(new ISubscriber[subscribers.size()]));
   mToken.publishAndWait(s3);
   verifySubscribers(new MockSubscriber[] {s1}, new MockSubscriber[] {s2, s3}, s3);
   // repeat one subscriber, add one new one
   subscribers.add(s2);
   assertEquals(2, subscribers.size());
   mToken.subscribeAll(subscribers.toArray(new ISubscriber[subscribers.size()]));
   // publish again, make sure each subscriber is notified only once
   mToken.publishAndWait(mToken);
   verifySubscribers(new MockSubscriber[] {s1, s2}, new MockSubscriber[] {s3}, mToken);
   // make sure that subscriber list can handle a mix of types
   DoNothingSubscriber x1 = new DoNothingSubscriber();
   ISubscriber[] mixedSubscribers = new ISubscriber[] {s1, x1};
   mToken.subscribeAll(mixedSubscribers);
   mToken.publishAndWait(mFeed);
   verifySubscribers(new MockSubscriber[] {s1, s2}, new MockSubscriber[] {s3}, mFeed);
   assertEquals(mFeed, x1.mData);
 }