private Set<Metric> getAllPredictedMetrics() {

    Set<Relationship> relationships =
        inventory.relationships().named(Configuration.PREDICTION_RELATIONSHIP).entities();

    Set<CanonicalPath> metricsCp = new HashSet<>();
    Set<CanonicalPath> metricTypesCp = new HashSet<>();
    Set<CanonicalPath> tenantsCp = new HashSet<>();

    for (Relationship relationship : relationships) {

      predictionRelationships.relationships().put(relationship.getTarget(), relationship);

      if (relationship.getTarget().getSegment().getElementType().equals(Metric.class)) {
        metricsCp.add(relationship.getTarget());
      } else if (relationship.getTarget().getSegment().getElementType().equals(MetricType.class)) {
        metricTypesCp.add(relationship.getTarget());
      } else if (relationship.getTarget().getSegment().getElementType().equals(Tenant.class)) {
        tenantsCp.add(relationship.getTarget());
      }
    }

    Set<Metric> metrics =
        inventory
            .tenants()
            .getAll()
            .feeds()
            .getAll()
            .metrics()
            .getAll(With.paths(metricsCp.toArray(new CanonicalPath[0])))
            .entities();
    Set<Metric> metricsUnderTypes =
        inventory
            .tenants()
            .getAll()
            .feeds()
            .getAll()
            .metricTypes()
            .getAll(With.paths(metricTypesCp.toArray(new CanonicalPath[0])))
            .metrics()
            .getAll()
            .entities();
    Set<Metric> metricsUnderTenant =
        inventory
            .tenants()
            .getAll(With.paths(tenantsCp.toArray(new CanonicalPath[0])))
            .feeds()
            .getAll()
            .metrics()
            .getAll()
            .entities();

    metrics.addAll(metricsUnderTypes);
    metrics.addAll(metricsUnderTenant);

    return metrics;
  }
  @Override
  public Metric metric(CanonicalPath metric) {
    Query query = Query.path().with(With.path(metric), With.type(Metric.class)).get();

    Page<Metric> page =
        inventory.execute(query, Metric.class, Pager.unlimited(Order.unspecified()));

    List<Metric> metrics = page.toList();
    return metrics.isEmpty() ? null : metrics.get(0);
  }
  @Override
  public Set<Metric> metricsUnderTenant(CanonicalPath tenant) {
    Set<Metric> entities =
        inventory
            .tenants()
            .get(tenant.ids().getTenantId())
            .feeds()
            .getAll()
            .metrics()
            .getAll()
            .entities();

    return entities;
  }
  @Override
  public Set<Metric> metricsOfType(CanonicalPath metricType) {
    Query query =
        Query.path()
            .with(With.path(metricType))
            .with(Related.by(Relationships.WellKnown.defines))
            .with(With.type(Metric.class))
            .get();

    Page<Metric> page =
        inventory.execute(query, Metric.class, Pager.unlimited(Order.unspecified()));

    List<Metric> metrics = page.toList();
    return new HashSet<>(metrics);
  }
  private static <C, T extends AbstractElement> void installAction(
      Inventory inventory,
      Set<Subscription> subscriptions,
      Class<T> entityClass,
      MessageSender sender,
      Action<C, T> action) {

    Interest<C, T> interest = Interest.in(entityClass).being(action);

    Subscription s =
        inventory
            .observable(interest)
            .subscribe(
                (c) -> {
                  // todo: ugly
                  Tenant t;
                  if (c instanceof AbstractElement) {
                    if (c instanceof Relationship) {
                      t = new Tenant(((Relationship) c).getSource().getRoot());
                    } else {
                      t = new Tenant(((AbstractElement) c).getPath().getRoot());
                    }
                  } else if (c instanceof Action.EnvironmentCopy) {
                    t = new Tenant(((Action.EnvironmentCopy) c).getSource().getPath().getRoot());
                  } else if (c instanceof Action.Update) {
                    t =
                        new Tenant(
                            ((AbstractElement) ((Action.Update) c).getOriginalEntity())
                                .getPath()
                                .getRoot());
                  } else {
                    throw new IllegalArgumentException(
                        "Unknown event type: " + c.getClass().getName());
                  }
                  sender.send(interest, t, c);
                });
    subscriptions.add(s);
  }