code: package objectexplorer;
  
  /**
   * A visitor that controls an object traversal. Implementations
   * of this interface are passed to {@link ObjectExplorer} exploration methods.
   *
   * @param <T> the type of the result that this visitor returns
   * (can be defined as {@code Void} to denote no result}.
   * @see ObjectExplorer
   */
  public interface ObjectVisitor<T> {
    /**
     * Visits an explored value (the whole chain from the root object
     * leading to the value is provided), and decides whether to continue
     * the exploration of that value.
     *
     * <p>In case the explored value is either primitive or {@code null}
     * (e.g., if {@code chain.isPrimitive() || chain.getValue() == null}),
     * the return value is meaningless and is ignored.
     *
     * @param chain the chain that leads to the explored value.
     * @return {@link Traversal#EXPLORE} to denote that the visited object
     * should be further explored, or {@link Traversal#SKIP} to avoid
     * exploring it.
     */
    Traversal visit(Chain chain);
  
    /**
     * Returns an arbitrary value (presumably constructed during the object
     * graph traversal).
     */
    T result();
  
    /**
     * Constants that denote how the traversal of a given object (chain)
     * should continue.
     */
    enum Traversal {
      /**
       * The visited object should be further explored.
       */
      EXPLORE,
  
      /**
       * The visited object should not be explored.
       */
      SKIP
    }
  }
  