/** @param node Node to remove. */
  public void removeMappedNode(GridNode node) {
    if (mappedDhtNodes.contains(node))
      mappedDhtNodes = new ArrayList<>(F.view(mappedDhtNodes, F.notEqualTo(node)));

    if (mappedNearNodes != null && mappedNearNodes.contains(node))
      mappedNearNodes = new ArrayList<>(F.view(mappedNearNodes, F.notEqualTo(node)));
  }
  /** {@inheritDoc} */
  @Override
  public final Map<UUID, GridNodeMetrics> metrics(Collection<UUID> nodeIds)
      throws GridSpiException {
    assert !F.isEmpty(nodeIds);

    long now = U.currentTimeMillis();

    Collection<UUID> expired = new LinkedList<>();

    for (UUID id : nodeIds) {
      GridNodeMetrics nodeMetrics = metricsMap.get(id);

      Long ts = tsMap.get(id);

      if (nodeMetrics == null || ts == null || ts < now - metricsExpireTime) expired.add(id);
    }

    if (!expired.isEmpty()) {
      Map<UUID, GridNodeMetrics> refreshed = metrics0(expired);

      for (UUID id : refreshed.keySet()) tsMap.put(id, now);

      metricsMap.putAll(refreshed);
    }

    return F.view(metricsMap, F.contains(nodeIds));
  }
 /**
  * @param g Grid.
  * @return Non-system caches.
  */
 private Collection<GridCacheConfiguration> caches(Grid g) {
   return F.view(
       Arrays.asList(g.configuration().getCacheConfiguration()),
       new GridPredicate<GridCacheConfiguration>() {
         @Override
         public boolean apply(GridCacheConfiguration c) {
           return c.getName() == null || !c.getName().equals(CU.UTILITY_CACHE_NAME);
         }
       });
 }
  /**
   * @param cctx Cache context.
   * @param prj Projection (optional).
   * @return Collection of data nodes in provided projection (if any).
   */
  private static Collection<GridNode> nodes(
      final GridCacheContext<?, ?> cctx, @Nullable final GridProjection prj) {
    assert cctx != null;

    return F.view(
        CU.allNodes(cctx),
        new P1<GridNode>() {
          @Override
          public boolean apply(GridNode n) {
            GridCacheDistributionMode mode = U.distributionMode(n, cctx.name());

            return (mode == PARTITIONED_ONLY || mode == NEAR_PARTITIONED)
                && (prj == null || prj.node(n.id()) != null);
          }
        });
  }