private void deleteComponent(
      final ComponentIdentifier id, final ComponentEventQueue ceq, final boolean deleteOrphans) {
    final NCSComponent component = getComponent(id);

    if (component == null) {
      throw new WebApplicationException(Status.BAD_REQUEST);
    }

    final Set<NCSComponent> parentComponents = component.getParentComponents();
    final Set<ComponentIdentifier> childrenIdentifiers =
        getIdentifiers(component.getSubcomponents());

    // first, we deal with orphans
    if (deleteOrphans) {
      for (final ComponentIdentifier subId : childrenIdentifiers) {
        handleOrphanedComponents(component, subId, ceq, deleteOrphans);
      }
    }

    // first, we remove this component from each of its parents
    for (final NCSComponent parent : parentComponents) {
      parent.getSubcomponents().remove(component);
      m_componentDao.update(parent);
    }

    // then we delete this component
    component.setSubcomponents(EMPTY_COMPONENT_SET);
    m_componentDao.delete(component);

    // and any events or alarms depending on it
    deleteEvents(id.getForeignSource(), id.getForeignId());
    deleteAlarms(id.getForeignSource(), id.getForeignId());

    // alert that the component is deleted
    ceq.componentDeleted(getIdentifier(component));

    // then alert about the parents
    sendUpdateEvents(ceq, getIdentifiers(parentComponents));
  }
  private void handleOrphanedComponents(
      final NCSComponent parent,
      final ComponentIdentifier child,
      final ComponentEventQueue ceq,
      final boolean deleteOrphans) {
    final ComponentIdentifier parentId = getIdentifier(parent);
    final NCSComponent childComponent = getComponent(child);

    final Set<ComponentIdentifier> childChildren =
        getIdentifiers(childComponent.getSubcomponents());
    final Set<ComponentIdentifier> childParents =
        getIdentifiers(childComponent.getParentComponents());

    LogUtils.tracef(this, "handleOrphanedComponents: parent: %s", parentId);
    LogUtils.tracef(this, "handleOrphanedComponents: child: %s", child);
    LogUtils.tracef(this, "handleOrphanedComponents: child's children: %s", childChildren);
    LogUtils.tracef(this, "handleOrphanedComponents: child's parents: %s", childParents);

    if (childParents.size() == 1) {
      final ComponentIdentifier childParent = childParents.iterator().next();
      if (childParent.equals(parentId)) {
        LogUtils.tracef(
            this,
            "handleOrphanedComponents: child (%s) has only one parent (%s) and it's being deleted.",
            child,
            childParent);
        deleteComponent(child, ceq, deleteOrphans);
      } else {
        LogUtils.tracef(
            this,
            "handleOrphanedComponents: child (%s) has only one parent (%s) but it's not the one we expected. This is weird.",
            child,
            childParent);
        ceq.componentUpdated(childParent);
      }
    } else {
      LogUtils.tracef(
          this,
          "handleOrphanedComponents: child (%s) has more than one parent, sending updates for remaining parents.",
          child);
      for (final ComponentIdentifier childParent : childParents) {
        ceq.componentUpdated(childParent);
      }
    }
  }