/** implements BundleActivator.start() */
  public void start(BundleContext bc) throws Exception {
    logger.info("starting popup message test ");

    bundleContext = bc;

    setName("PopupMessageHandlerSLick");

    Hashtable<String, String> properties = new Hashtable<String, String>();

    properties.put("service.pid", getName());

    // we maybe are running on machine without WM and systray
    // (test server machine), skip tests
    if (ServiceUtils.getService(bc, SystrayService.class) != null) {
      addTest(TestPopupMessageHandler.suite());
    }

    bundleContext.registerService(getClass().getName(), this, properties);
  }
  /**
   * The method would add a subscription for a contact, wait for a subscription event confirming the
   * subscription, then change the status of the newly added contact (which is actually the
   * IcqTesterAgent) and make sure that the corresponding notification events have been generated.
   *
   * @throws java.lang.Exception if an exception occurs during testing.
   */
  public void postTestSubscribe() throws Exception {
    logger.debug("Testing Subscription and Subscription Event Dispatch.");

    // First create a subscription and verify that it really gets created.
    SubscriptionEventCollector subEvtCollector = new SubscriptionEventCollector();

    logger.trace("set Auth Handler");
    operationSetPresence.setAuthorizationHandler(authEventCollector);

    synchronized (authEventCollector) {
      authEventCollector.authorizationRequestReason = "Please deny my request!";
      fixture.testerAgent.getAuthCmdFactory().responseReasonStr =
          "First authorization I will Deny!!!";
      fixture.testerAgent.getAuthCmdFactory().ACCEPT = false;
      operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN());

      // this one collects event that the buddy has been added
      // to the list as awaiting
      SubscriptionEventCollector moveEvtCollector = new SubscriptionEventCollector();
      operationSetPresence.addSubscriptionListener(moveEvtCollector);

      logger.debug("Waiting for authorization error and authorization response...");
      authEventCollector.waitForAuthResponse(15000);
      assertTrue(
          "Error adding buddy not recieved or the buddy("
              + fixture.testerAgent.getIcqUIN()
              + ") doesn't require authorization",
          authEventCollector.isAuthorizationRequestSent);

      assertNotNull(
          "Agent haven't received any reason for authorization",
          fixture.testerAgent.getAuthCmdFactory().requestReasonStr);
      assertEquals(
          "Error sent request reason is not as the received one",
          authEventCollector.authorizationRequestReason,
          fixture.testerAgent.getAuthCmdFactory().requestReasonStr);

      logger.debug(
          "authEventCollector.isAuthorizationResponseReceived "
              + authEventCollector.isAuthorizationResponseReceived);

      assertTrue("Response not received!", authEventCollector.isAuthorizationResponseReceived);

      boolean isAcceptedAuthReuest =
          authEventCollector.response.getResponseCode().equals(AuthorizationResponse.ACCEPT);
      assertEquals(
          "Response is not as the sent one",
          fixture.testerAgent.getAuthCmdFactory().ACCEPT,
          isAcceptedAuthReuest);
      assertNotNull(
          "We didn't receive any reason! ", authEventCollector.authorizationResponseString);

      assertEquals(
          "The sent response reason is not as the received one",
          fixture.testerAgent.getAuthCmdFactory().responseReasonStr,
          authEventCollector.authorizationResponseString);

      // here we must wait for server to move the awaiting buddy
      // to the first specified  group
      synchronized (moveEvtCollector) {
        moveEvtCollector.waitForEvent(20000);
        // don't want any more events
        operationSetPresence.removeSubscriptionListener(moveEvtCollector);
      }

      Contact c = operationSetPresence.findContactByID(fixture.testerAgent.getIcqUIN());
      logger.debug("I will remove " + c + " from group : " + c.getParentContactGroup());

      UnsubscribeWait unsubscribeEvtCollector = new UnsubscribeWait();
      operationSetPresence.addSubscriptionListener(unsubscribeEvtCollector);

      synchronized (unsubscribeEvtCollector) {
        operationSetPresence.unsubscribe(c);
        logger.debug("Waiting to be removed...");
        unsubscribeEvtCollector.waitForUnsubscribre(20000);

        logger.debug("Received unsubscribed ok or we lost patients!");

        // don't want any more events
        operationSetPresence.removeSubscriptionListener(unsubscribeEvtCollector);
      }

      // so we haven't asserted so everithing is fine lets try to be authorized
      authEventCollector.authorizationRequestReason = "Please accept my request!";
      fixture.testerAgent.getAuthCmdFactory().responseReasonStr =
          "Second authorization I will Accept!!!";
      fixture.testerAgent.getAuthCmdFactory().ACCEPT = true;

      // clear some things
      authEventCollector.isAuthorizationRequestSent = false;
      authEventCollector.isAuthorizationResponseReceived = false;
      authEventCollector.authorizationResponseString = null;

      logger.debug(
          "I will add buddy does it exists ?  "
              + (operationSetPresence.findContactByID(fixture.testerAgent.getIcqUIN()) != null));
      // add the listener beacuse now our authorization will be accepted
      // and so the buddy will be finally added to the list
      operationSetPresence.addSubscriptionListener(subEvtCollector);
      // subscribe again so we can trigger again the authorization procedure
      operationSetPresence.subscribe(fixture.testerAgent.getIcqUIN());

      logger.debug(
          "Waiting ... Subscribe must fail and the authorization process "
              + "to be trigered again so waiting for auth response ...");
      authEventCollector.waitForAuthResponse(15000);

      assertTrue(
          "Error adding buddy not recieved or the buddy("
              + fixture.testerAgent.getIcqUIN()
              + ") doesn't require authorization",
          authEventCollector.isAuthorizationRequestSent);

      assertNotNull(
          "Agent haven't received any reason for authorization",
          fixture.testerAgent.getAuthCmdFactory().requestReasonStr);

      // not working for now
      assertEquals(
          "Error sent request reason",
          authEventCollector.authorizationRequestReason,
          fixture.testerAgent.getAuthCmdFactory().requestReasonStr);

      // wait for authorization process to be finnished
      // the modification of buddy (server will inform us
      // that he removed - awaiting authorization flag)
      Object obj = new Object();
      synchronized (obj) {
        logger.debug("wait for authorization process to be finnished");
        obj.wait(10000);
        logger.debug("Stop waiting!");
      }

      subEvtCollector.waitForEvent(10000);
      // don't want any more events
      operationSetPresence.removeSubscriptionListener(subEvtCollector);
    }

    // after adding awaitingAuthorization group here are catched 3 events
    // 1 - creating unresolved contact
    // 2 - move of the contact to awaitingAuthorization group
    // 3 - move of the contact from awaitingAuthorization group to original group
    assertTrue(
        "Subscription event dispatching failed.", subEvtCollector.collectedEvents.size() > 0);

    EventObject evt = null;

    Iterator<EventObject> events = subEvtCollector.collectedEvents.iterator();
    while (events.hasNext()) {
      EventObject elem = events.next();
      if (elem instanceof SubscriptionEvent) {
        if (((SubscriptionEvent) elem).getEventID() == SubscriptionEvent.SUBSCRIPTION_CREATED)
          evt = (SubscriptionEvent) elem;
      }
    }

    Object source = null;
    Contact srcContact = null;
    ProtocolProviderService srcProvider = null;

    // the event can be SubscriptionEvent and the new added one
    // SubscriptionMovedEvent

    if (evt instanceof SubscriptionEvent) {
      SubscriptionEvent subEvt = (SubscriptionEvent) evt;

      source = subEvt.getSource();
      srcContact = subEvt.getSourceContact();
      srcProvider = subEvt.getSourceProvider();
    }

    assertEquals(
        "SubscriptionEvent Source:",
        fixture.testerAgent.getIcqUIN(),
        ((Contact) source).getAddress());
    assertEquals(
        "SubscriptionEvent Source Contact:",
        fixture.testerAgent.getIcqUIN(),
        srcContact.getAddress());
    assertSame("SubscriptionEvent Source Provider:", fixture.provider, srcProvider);

    subEvtCollector.collectedEvents.clear();

    // make the user agent tester change its states and make sure we are
    // notified
    logger.debug("Testing presence notifications.");
    IcqStatusEnum testerAgentOldStatus = fixture.testerAgent.getPresneceStatus();
    IcqStatusEnum testerAgentNewStatus = IcqStatusEnum.FREE_FOR_CHAT;
    long testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_FFC;

    // in case we are by any chance already in a FREE_FOR_CHAT status, we'll
    // be changing to something else
    if (testerAgentOldStatus.equals(testerAgentNewStatus)) {
      testerAgentNewStatus = IcqStatusEnum.DO_NOT_DISTURB;
      testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_DND;
    }

    // now do the actual status notification testing
    ContactPresenceEventCollector contactPresEvtCollector =
        new ContactPresenceEventCollector(fixture.testerAgent.getIcqUIN(), testerAgentNewStatus);
    operationSetPresence.addContactPresenceStatusListener(contactPresEvtCollector);

    synchronized (contactPresEvtCollector) {
      if (!fixture.testerAgent.enterStatus(testerAgentNewStatusLong)) {
        throw new RuntimeException(
            "Tester UserAgent Failed to switch to the "
                + testerAgentNewStatus.getStatusName()
                + " state.");
      }
      // we may already have the event, but it won't hurt to check.
      contactPresEvtCollector.waitForEvent(12000);
      operationSetPresence.removeContactPresenceStatusListener(contactPresEvtCollector);
    }

    if (contactPresEvtCollector.collectedEvents.size() == 0) {
      logger.info(
          "PROBLEM. Authorisation process doesn't have finnished "
              + "Server doesn't report us for changing authorization flag! Will try to authorize once again");

      fixture.testerAgent.sendAuthorizationReplay(
          fixture.icqAccountID.getUserID(),
          fixture.testerAgent.getAuthCmdFactory().responseReasonStr,
          fixture.testerAgent.getAuthCmdFactory().ACCEPT);

      Object obj = new Object();
      synchronized (obj) {
        logger.debug("wait for authorization process to be finnished for second time");
        obj.wait(10000);
        logger.debug("Stop waiting!");
      }

      testerAgentOldStatus = fixture.testerAgent.getPresneceStatus();
      testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_FFC;

      // in case we are by any chance already in a FREE_FOR_CHAT status, we'll
      // be changing to something else
      if (testerAgentOldStatus.equals(testerAgentNewStatus)) {
        testerAgentNewStatus = IcqStatusEnum.OCCUPIED;
        testerAgentNewStatusLong = FullUserInfo.ICQSTATUS_OCCUPIED;
      }

      contactPresEvtCollector =
          new ContactPresenceEventCollector(fixture.testerAgent.getIcqUIN(), testerAgentNewStatus);
      operationSetPresence.addContactPresenceStatusListener(contactPresEvtCollector);

      synchronized (contactPresEvtCollector) {
        if (!fixture.testerAgent.enterStatus(testerAgentNewStatusLong)) {
          throw new RuntimeException(
              "Tester UserAgent Failed to switch to the "
                  + testerAgentNewStatus.getStatusName()
                  + " state.");
        }
        // we may already have the event, but it won't hurt to check.
        contactPresEvtCollector.waitForEvent(12000);
        operationSetPresence.removeContactPresenceStatusListener(contactPresEvtCollector);
      }
    }

    assertEquals(
        "Presence Notif. event dispatching failed.",
        1,
        contactPresEvtCollector.collectedEvents.size());
    ContactPresenceStatusChangeEvent presEvt =
        (ContactPresenceStatusChangeEvent) contactPresEvtCollector.collectedEvents.get(0);

    assertEquals(
        "Presence Notif. event  Source:",
        fixture.testerAgent.getIcqUIN(),
        ((Contact) presEvt.getSource()).getAddress());
    assertEquals(
        "Presence Notif. event  Source Contact:",
        fixture.testerAgent.getIcqUIN(),
        presEvt.getSourceContact().getAddress());
    assertSame(
        "Presence Notif. event  Source Provider:", fixture.provider, presEvt.getSourceProvider());

    PresenceStatus reportedNewStatus = presEvt.getNewStatus();
    PresenceStatus reportedOldStatus = presEvt.getOldStatus();

    assertEquals("Reported new PresenceStatus: ", testerAgentNewStatus, reportedNewStatus);

    // don't require equality between the reported old PresenceStatus and
    // the actual presence status of the tester agent because a first
    // notification is not supposed to have the old status as it really was.
    assertNotNull("Reported old PresenceStatus: ", reportedOldStatus);

    /** @todo tester agent changes status message we see the new message */
    /** @todo we should see the alias of the tester agent. */
    Object obj = new Object();
    synchronized (obj) {
      logger.debug("wait a moment. give time to server");
      obj.wait(4000);
    }
  }
  public static double testCostAndGradientCurrentParameters(Minimizable.ByGradient minable) {
    Matrix parameters = minable.getParameters(minable.getNewMatrix());
    double cost = minable.getCost();
    // the gradient from the minimizable function
    Matrix analyticGradient = minable.getCostGradient(minable.getNewMatrix());
    // the gradient calculate from the slope of the cost
    Matrix empiricalGradient = (Matrix) analyticGradient.cloneMatrix();
    // This setting of epsilon should make the individual elements of
    // the analytical gradient and the empirical gradient equal.  This
    // simplifies the comparison of the individual dimensions of the
    // gradient and thus makes debugging easier.
    double epsilon = 0.1 / analyticGradient.twoNorm();
    double tolerance = epsilon * 5;
    System.out.println("epsilon = " + epsilon + " tolerance=" + tolerance);

    // Check each direction, perturb it, measure new cost,
    // and make sure it agrees with the gradient from minable.getCostGradient()
    for (int i = 0; i < parameters.singleSize(); i++) {
      double param = parameters.singleValue(i);
      parameters.setSingleValue(i, param + epsilon);
      // logger.fine ("Parameters:"); parameters.print();
      minable.setParameters(parameters);
      double epsCost = minable.getCost();
      double slope = (epsCost - cost) / epsilon;
      System.out.println(
          "cost="
              + cost
              + " epsCost="
              + epsCost
              + " slope["
              + i
              + "] = "
              + slope
              + " gradient[]="
              + analyticGradient.singleValue(i));
      assert (!Double.isNaN(slope));
      logger.fine(
          "TestMinimizable checking singleIndex "
              + i
              + ": gradient slope = "
              + analyticGradient.singleValue(i)
              + ", cost+epsilon slope = "
              + slope
              + ": slope difference = "
              + Math.abs(slope - analyticGradient.singleValue(i)));
      // No negative below because the gradient points in the direction
      // of maximizing the function.
      empiricalGradient.setSingleValue(i, slope);
      parameters.setSingleValue(i, param);
    }
    // Normalize the matrices to have the same L2 length
    System.out.println("empiricalGradient.twoNorm = " + empiricalGradient.twoNorm());
    analyticGradient.timesEquals(1.0 / analyticGradient.twoNorm());
    empiricalGradient.timesEquals(1.0 / empiricalGradient.twoNorm());
    // logger.info ("AnalyticGradient:"); analyticGradient.print();
    // logger.info ("EmpiricalGradient:"); empiricalGradient.print();
    // Return the angle between the two vectors, in radians
    double angle = Math.acos(analyticGradient.dotProduct(empiricalGradient));
    logger.info("TestMinimizable angle = " + angle);
    if (Math.abs(angle) > tolerance)
      throw new IllegalStateException("Gradient/Cost mismatch: angle=" + angle);
    if (Double.isNaN(angle)) throw new IllegalStateException("Gradient/Cost error: angle is NaN!");
    return angle;
  }
  public void testStatelessSearch()
      throws org.jzkit.configuration.api.ConfigurationException, org.jzkit.search.SearchException,
          org.jzkit.search.util.ResultSet.IRResultSetException,
          org.jzkit.search.util.QueryModel.InvalidQueryException {

    Logger log = Logger.getLogger(TestService.class.getName());

    log.info("Starting jzkit2 server...");

    RecordFormatSpecification request_spec = new ArchetypeRecordFormatSpecification("F");
    ExplicitRecordFormatSpecification display_spec =
        new ExplicitRecordFormatSpecification("text:html:F");

    ApplicationContext app_context =
        new ClassPathXmlApplicationContext("TestApplicationContext.xml");
    log.info("JZKit server startup completed");

    Vector collection_ids = new Vector();
    collection_ids.add("LC/BOOKS");

    QueryModel qm = new PrefixString("@attrset bib-1 @attr 1=4 Science");

    System.err.println("Processing search......");

    try {
      Map additional_properties = new HashMap();
      additional_properties.put("base_dir", "/a/b/c/d");

      StatelessQueryService stateless_query_service =
          (StatelessQueryService) app_context.getBean("StatelessQueryService");

      org.jzkit.search.landscape.SimpleLandscapeSpecification landscape =
          new org.jzkit.search.landscape.SimpleLandscapeSpecification(collection_ids);
      // Test 1 - Kick off a search
      StatelessSearchResultsPageDTO rp =
          stateless_query_service.getResultsPageFor(
              null, qm, landscape, 1, 5, request_spec, display_spec, additional_properties);

      if (rp != null) {
        System.err.println(
            "Result Set Size....."
                + rp.total_hit_count
                + " records - result contains "
                + rp.number_of_records
                + " records");
        System.err.println("Result Set ID : " + rp.result_set_id);
      } else {
        System.err.println("Results page was null");
      }

      if (rp.records != null) {
        for (int i = 0; ((i < rp.records.length) && (i < 25)); i++) {
          System.err.println(
              "Getting next record (" + i + " out of " + rp.number_of_records + ").....");
          InformationFragment frag = rp.records[i];
          System.err.println(frag);
        }
      }

      // Test 2 - use the result set ID to get a page of requests
      rp =
          stateless_query_service.getResultsPageFor(
              rp.result_set_id,
              qm,
              landscape,
              6,
              5,
              request_spec,
              display_spec,
              additional_properties);

      if (rp.records != null) {
        for (int i = 0; ((i < rp.records.length) && (i < 25)); i++) {
          System.err.println(
              "Getting next record (" + i + " out of " + rp.number_of_records + ").....");
          InformationFragment frag = rp.records[i];
          System.err.println(frag);
        }
      }

      // Test 3 - Use the query to get a cache hit
      rp =
          stateless_query_service.getResultsPageFor(
              null, qm, landscape, 6, 5, request_spec, display_spec, additional_properties);

      if (rp.records != null) {
        for (int i = 0; ((i < rp.records.length) && (i < 25)); i++) {
          System.err.println(
              "Getting next record (" + i + " out of " + rp.number_of_records + ").....");
          InformationFragment frag = rp.records[i];
          System.err.println(frag);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }