/**
   * Calculates and returns a path that satisfies the required tables list or null if one cannot be
   * found
   *
   * @param requiredTables Tables that are required to be in path
   * @return Path with smallest number of relationships to ensure all required tables are included
   */
  public Path getPath(PathType searchTechnique, List<BusinessTable> requiredTables) {
    // if reset works and validity check passes, build path
    if (reset(requiredTables) && isValid(searchTechnique)) {
      logger.debug("Path determined sucessfully");

      Path path = new Path();
      for (Arc arc : arcs) {
        if (arc.isRequired()) {
          if (logger.isDebugEnabled()) {
            logger.debug("Arc selected for path: " + arc);
          }
          path.addRelationship(arc.getRelationship());
        } else if (logger.isDebugEnabled()) {
          logger.debug(
              "Arc not used for path: Requirement Known["
                  + arc.isRequirementKnown()
                  + "], Required["
                  + arc.isRequired()
                  + "]");
        }
      }

      if (logger.isDebugEnabled()) {
        for (Node n : nodes) {
          logger.debug(
              "Node selection state: Requirement Known["
                  + n.isRequirementKnown()
                  + "], Required["
                  + n.isRequired()
                  + "]");
        }
      }
      if (path.size() > 0) {
        return path;
      }
    }

    return null;
  }