int DCPS_IR_Participant::find_topic_reference(OpenDDS::DCPS::RepoId topicId,
                                              DCPS_IR_Topic*& topic)
{
  DCPS_IR_Topic_Map::iterator where = this->topicRefs_.find(topicId);

  if (where != this->topicRefs_.end()) {
    topic = where->second;

    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter topic_converter(topicId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::find_topic_reference: ")
                 ACE_TEXT("participant %C found topic %C at %x.\n"),
                 std::string(part_converter).c_str(),
                 std::string(topic_converter).c_str(),
                 topic));
    }

    return 0;

  } else {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter topic_converter(topicId);
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::find_topic_reference: ")
               ACE_TEXT("participant %C unable to find topic %C.\n"),
               std::string(part_converter).c_str(),
               std::string(topic_converter).c_str()));
    topic = 0;
    return -1;
  }
}
int DCPS_IR_Participant::find_subscription_reference(OpenDDS::DCPS::RepoId subId,
                                                     DCPS_IR_Subscription*& sub)
{
  DCPS_IR_Subscription_Map::iterator where = this->subscriptions_.find(subId);

  if (where != this->subscriptions_.end()) {
    sub = where->second;

    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::find_subscription_reference: ")
                 ACE_TEXT("participant %C found subscription %C at 0x%x.\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str(),
                 sub));
    }

    return 0;

  } else {
    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::find_subscription_reference: ")
                 ACE_TEXT("participant %C could not find subscription %C.\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str()));
    }
    sub = 0;
    return -1;
  }
}
int DCPS_IR_Participant::remove_subscription(OpenDDS::DCPS::RepoId subId)
{
  DCPS_IR_Subscription_Map::iterator where = this->subscriptions_.find(subId);

  if (where != this->subscriptions_.end()) {
    DCPS_IR_Topic* topic = where->second->get_topic();
    topic->remove_subscription_reference(where->second);

    if (0 != where->second->remove_associations(false)) {
      // N.B. As written today, this branch will never be taken.
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_ERROR((LM_ERROR,
                 ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::remove_subscription: ")
                 ACE_TEXT("participant %C unable to remove associations from subscription %C\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str()));
      return -1;
    }

    this->domain_->dispose_subscription_bit(where->second);
    delete where->second;
    topic->release(false);
    this->subscriptions_.erase(where);

    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::remove_subscription: ")
                 ACE_TEXT("participant %C removed subscription %C.\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str()));
    }

    return 0;

  } else {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::remove_subscription: ")
               ACE_TEXT("participant %C unable to remove subscription %C.\n"),
               std::string(part_converter).c_str(),
               std::string(sub_converter).c_str()));
    return -1;
  }
}
void DCPS_IR_Participant::ignore_topic(OpenDDS::DCPS::RepoId id)
{
  if (OpenDDS::DCPS::DCPS_debug_level > 0) {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter ignore_converter(id);
    ACE_DEBUG((LM_DEBUG,
               ACE_TEXT("(%P|%t) DCPS_IR_Participant::ignore_topic: ")
               ACE_TEXT("participant %C now ignoring topic %C.\n"),
               std::string(part_converter).c_str(),
               std::string(ignore_converter).c_str()));
  }

  ignoredTopics_.insert(id);

  // disassociate any publications
  for (DCPS_IR_Publication_Map::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current) {
    current->second->disassociate_topic(id);
  }

  // disassociate any subscriptions
  for (DCPS_IR_Subscription_Map::const_iterator current = this->subscriptions_.begin();
       current != this->subscriptions_.end();
       ++current) {
    current->second->disassociate_topic(id);
  }
}
DCPS_IR_Participant::~DCPS_IR_Participant()
{
  for (DCPS_IR_Subscription_Map::const_iterator current = this->subscriptions_.begin();
       current != this->subscriptions_.end();
       ++current) {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter sub_converter(current->first);
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::~DCPS_IR_Participant: ")
               ACE_TEXT("domain %d participant %C removing subscription %C.\n"),
               this->domain_->get_id(),
               std::string(part_converter).c_str(),
               std::string(sub_converter).c_str()));
    remove_subscription(current->first);
  }

  for (DCPS_IR_Publication_Map::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current) {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter pub_converter(current->first);
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::~DCPS_IR_Participant: ")
               ACE_TEXT("domain %d participant %C removing publication %C.\n"),
               this->domain_->get_id(),
               std::string(part_converter).c_str(),
               std::string(pub_converter).c_str()));
    remove_publication(current->first);
  }

  for (DCPS_IR_Topic_Map::const_iterator current = this->topicRefs_.begin();
       current != this->topicRefs_.end();
       ++current) {
    OpenDDS::DCPS::RepoIdConverter part_converter(id_);
    OpenDDS::DCPS::RepoIdConverter topic_converter(current->first);
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: DCPS_IR_Participant::~DCPS_IR_Participant: ")
               ACE_TEXT("domain %d participant %C retained topic %C.\n"),
               this->domain_->get_id(),
               std::string(part_converter).c_str(),
               std::string(topic_converter).c_str()));
  }
}
int DCPS_IR_Participant::add_topic_reference(DCPS_IR_Topic* topic)
{
  OpenDDS::DCPS::RepoId topicId = topic->get_id();
  DCPS_IR_Topic_Map::iterator where = this->topicRefs_.find(topicId);

  if (where == this->topicRefs_.end()) {
    this->topicRefs_.insert(
      where, DCPS_IR_Topic_Map::value_type(topicId, topic));

    if (isBitPublisher_) {
      topic->set_bit_status(isBitPublisher_);
    }

    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter topic_converter(topicId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::add_topic_reference: ")
                 ACE_TEXT("participant %C successfully added topic %C at 0x%x.\n"),
                 std::string(part_converter).c_str(),
                 std::string(topic_converter).c_str(),
                 topic));
    }

    return 0;

  } else {
    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter topic_converter(topicId);
      ACE_DEBUG((LM_NOTICE,
                 ACE_TEXT("(%P|%t) NOTICE: DCPS_IR_Participant::add_topic_reference: ")
                 ACE_TEXT("participant %C attempted to add existing topic %C.\n"),
                 std::string(part_converter).c_str(),
                 std::string(topic_converter).c_str()));
    }

    return 1;
  }
}
int DCPS_IR_Participant::add_subscription(DCPS_IR_Subscription* sub)
{
  OpenDDS::DCPS::RepoId subId = sub->get_id();
  DCPS_IR_Subscription_Map::iterator where = this->subscriptions_.find(subId);

  if (where == this->subscriptions_.end()) {
    this->subscriptions_.insert(
      where, DCPS_IR_Subscription_Map::value_type(subId, sub));

    if (isBitPublisher_) {
      sub->set_bit_status(isBitPublisher_);
    }

    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_DEBUG((LM_DEBUG,
                 ACE_TEXT("(%P|%t) DCPS_IR_Participant::add_subscription: ")
                 ACE_TEXT("participant %C successfully added subscription %C at 0x%x.\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str(),
                 sub));
    }

    return 0;

  } else {
    if (OpenDDS::DCPS::DCPS_debug_level > 0) {
      OpenDDS::DCPS::RepoIdConverter part_converter(id_);
      OpenDDS::DCPS::RepoIdConverter sub_converter(subId);
      ACE_ERROR((LM_NOTICE,
                 ACE_TEXT("(%P|%t) NOTICE: DCPS_IR_Participant::add_subscription: ")
                 ACE_TEXT("participant %C attempted to add existing subscription %C.\n"),
                 std::string(part_converter).c_str(),
                 std::string(sub_converter).c_str()));
    }

    return 1;
  }
}
OpenDDS::DCPS::TopicStatus DCPS_IR_Domain::remove_topic(DCPS_IR_Participant* part,
                                                        DCPS_IR_Topic*& topic)
{
  DCPS_IR_Topic_Description* description = topic->get_topic_description();

  if (description->remove_topic(topic) != 0) {
    // An unknown error means that the description may still
    // have the topic in its topic set.  We can't remove it.
    // The system is an inconsistent state!
    throw OpenDDS::DCPS::Invalid_Topic();
  }

  if (description->get_number_topics() == 0) {
    // Remove the topic description
    if (remove_topic_description(description) != 0) {
      // An unknown error means that the description may still
      // have the topic in its topic set.
      ACE_ERROR((LM_ERROR,
                 ACE_TEXT("(%P|%t) ERROR: Topic Description %C %C  ")
                 ACE_TEXT("was not correctly removed from Domain %d"),
                 description->get_name(),
                 description->get_dataTypeName(),
                 id_));

    } else {
      delete description;
      description = 0;
    }
  }

  // description variable is invalid after this point

  if (part->remove_topic_reference(topic->get_id(), topic) != 0) {
    OpenDDS::DCPS::RepoIdConverter part_converter(part->get_id());
    OpenDDS::DCPS::RepoIdConverter topic_converter(topic->get_id());
    ACE_ERROR((LM_ERROR,
               ACE_TEXT("(%P|%t) ERROR: Domain %d Topic %C ")
               ACE_TEXT("was not correctly removed from Participant %C"),
               id_,
               std::string(topic_converter).c_str(),
               std::string(part_converter).c_str()));
  }

  // Dispose the BIT information
  dispose_topic_bit(topic);

  topic->release(true);
  topic = 0;
  return OpenDDS::DCPS::REMOVED;
}
void DCPS_IR_Participant::remove_all_dependents(CORBA::Boolean notify_lost)
{
  // remove all the publications associations
  {
    DCPS_IR_Publication_Map::const_iterator next = this->publications_.begin();

    while (next != this->publications_.end()) {
      DCPS_IR_Publication_Map::const_iterator current = next;
      ++ next;
      DCPS_IR_Topic* topic = current->second->get_topic();
      topic->remove_publication_reference(current->second);

      if (0 != current->second->remove_associations(notify_lost)) {
        return;
      }

      topic->release(false);
    }
  }

  {
    DCPS_IR_Subscription_Map::const_iterator next = this->subscriptions_.begin();

    while (next != this->subscriptions_.end()) {
      DCPS_IR_Subscription_Map::const_iterator current = next;
      ++ next;
      DCPS_IR_Topic* topic = current->second->get_topic();
      topic->remove_subscription_reference(current->second);

      if (0 != current->second->remove_associations(notify_lost)) {
        return;
      }

      topic->release(false);
    }
  }

  {
    DCPS_IR_Topic_Map::const_iterator next = this->topicRefs_.begin();

    while (next != this->topicRefs_.end()) {
      DCPS_IR_Topic_Map::const_iterator current = next;
      ++ next;

      // Notify the federation to remove the topic.
      if (this->um_ && (this->isBitPublisher() == false)) {
        Update::IdPath path(
          this->domain_->get_id(),
          this->get_id(),
          current->second->get_id());
        this->um_->destroy(path, Update::Topic);

        if (OpenDDS::DCPS::DCPS_debug_level > 4) {
          OpenDDS::DCPS::RepoId id = current->second->get_id();
          OpenDDS::DCPS::RepoIdConverter converter(id);
          ACE_DEBUG((LM_DEBUG,
                     ACE_TEXT("(%P|%t) DCPS_IR_Participant::remove_all_dependents: ")
                     ACE_TEXT("pushing deletion of topic %C in domain %d.\n"),
                     std::string(converter).c_str(),
                     this->domain_->get_id()));
        }

        // Remove the topic ourselves.
        // N.B. This call sets the second (reference) argument to 0, so when
        //      clear() is called below, no destructor is (re)called.

        // Get the topic id and topic point before remove_topic since it
        // invalidates the iterator. Accessing after removal got SEGV.
        OpenDDS::DCPS::RepoId id = current->first;
        DCPS_IR_Topic* topic = current->second;

        this->domain_->remove_topic(this, topic);

        if (OpenDDS::DCPS::DCPS_debug_level > 9) {
          OpenDDS::DCPS::RepoIdConverter part_converter(id_);
          OpenDDS::DCPS::RepoIdConverter topic_converter(id);
          ACE_DEBUG((LM_DEBUG,
                     ACE_TEXT("(%P|%t) DCPS_IR_Participant::remove_all_dependents: ")
                     ACE_TEXT("domain %d participant %C removed topic %C.\n"),
                     this->domain_->get_id(),
                     std::string(part_converter).c_str(),
                     std::string(topic_converter).c_str()));
        }
      }
    }
  }

  // Clear the Topic container of null pointers.
  this->topicRefs_.clear();

  // The publications and subscriptions can NOT be deleted until after all
  // the associations have been removed.  Otherwise an access violation
  // can occur because a publication and subscription of this participant
  // could be associated.

  // delete all the publications
  for (DCPS_IR_Publication_Map::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current) {
    // Notify the federation to destroy the publication.
    if (this->um_ && (this->isBitPublisher() == false)) {
      Update::IdPath path(
        this->domain_->get_id(),
        this->get_id(),
        current->second->get_id());
      this->um_->destroy(path, Update::Actor, Update::DataWriter);

      if (OpenDDS::DCPS::DCPS_debug_level > 4) {
        OpenDDS::DCPS::RepoId id = current->second->get_id();
        OpenDDS::DCPS::RepoIdConverter converter(id);
        ACE_DEBUG((LM_DEBUG,
                   ACE_TEXT("(%P|%t) DCPS_IR_Participant::remove_all_dependents: ")
                   ACE_TEXT("pushing deletion of publication %C in domain %d.\n"),
                   std::string(converter).c_str(),
                   this->domain_->get_id()));
      }
    }
    // delete the publication
    delete current->second;
  }

  // Clear the container.
  this->publications_.clear();

  // delete all the subscriptions
  for (DCPS_IR_Subscription_Map::const_iterator current
       = this->subscriptions_.begin();
       current != this->subscriptions_.end();
       ++current) {
    // Notify the federation to destroy the subscription.
    if (this->um_ && (this->isBitPublisher() == false)) {
      Update::IdPath path(
        this->domain_->get_id(),
        this->get_id(),
        current->second->get_id());
      this->um_->destroy(path, Update::Actor, Update::DataReader);

      if (OpenDDS::DCPS::DCPS_debug_level > 4) {
        OpenDDS::DCPS::RepoId id = current->second->get_id();
        OpenDDS::DCPS::RepoIdConverter converter(id);
        ACE_DEBUG((LM_DEBUG,
                   ACE_TEXT("(%P|%t) DCPS_IR_Participant::remove_all_dependents: ")
                   ACE_TEXT("pushing deletion of subscription %C in domain %d.\n"),
                   std::string(converter).c_str(),
                   this->domain_->get_id()));
      }
    }
    // delete the subscription
    delete current->second;
  }

  // Clear the container.
  this->subscriptions_.clear();
}