@Override
  public void addDevice(ICpDeviceItem item) {
    if (item == null) return;

    EDeviceHierarchyLevel eLevel = item.getLevel();
    int level = eLevel.ordinal();

    if (fLevel == level || fLevel == EDeviceHierarchyLevel.PROCESSOR.ordinal()) {
      ICpPack pack = item.getPack();
      String packId = pack.getId();
      if (fDevices == null) fDevices = new TreeMap<String, ICpDeviceItem>(new AlnumComparator());

      ICpDeviceItem device = fDevices.get(packId);
      if (device == null) {
        fDevices.put(packId, item);
      }
      if (fLevel == EDeviceHierarchyLevel.PROCESSOR.ordinal()) return;
      Collection<ICpDeviceItem> subItems = item.getDeviceItems();
      if (subItems != null && !subItems.isEmpty()) {
        for (ICpDeviceItem i : subItems) {
          addDevice(i);
        }
      } else if (level >= EDeviceHierarchyLevel.DEVICE.ordinal() && item.getProcessorCount() > 1) {
        // add processor leaves
        Map<String, ICpItem> processors = item.getProcessors();
        for (Entry<String, ICpItem> e : processors.entrySet()) {
          String procName = item.getName() + ":" + e.getKey();
          addDeviceItem(item, procName, EDeviceHierarchyLevel.PROCESSOR.ordinal());
        }
      }
      return;
    } else if (fLevel == EDeviceHierarchyLevel.ROOT.ordinal()) {
      String vendorName = Vendor.getOfficialVendorName(item.getVendor());
      addDeviceItem(item, vendorName, EDeviceHierarchyLevel.VENDOR.ordinal());
      return;
    } else if (fLevel > level) { // should not happen if algorithm is correct
      return;
    }

    // other cases
    addDeviceItem(item, item.getName(), level);
  }
 @Override
 public boolean isDevice() {
   if (getLevel() < EDeviceHierarchyLevel.DEVICE.ordinal()) return false;
   if (hasChildren()) return false;
   return getDevice() != null;
 }