/**
   * Answers whether a given "agent" is authorized to perform a given "action" on the target entity,
   * that could be a register or a code. Unspecified constraints (null values) are considered as
   * all. e.g.: agent-null-target would return whether the agent is allowed all operations on the
   * target. If no authorization directives are provided by the AuthManager, the request is
   *
   * @param agent the URI of the agent performing the action. Through the code the agent is also
   *     referred to as "actor" or "actorURI". A null values stands for all agents.
   * @param action the URI of the action. A null value stands for all actions.
   * @param entity the URI of the target entity. A null value stands for all targets.
   * @throws ModelException
   * @throws RegistryAccessException
   */
  public boolean can(String agent, String action, String entity)
      throws RegistryAccessException, ModelException {
    Loggers.authLogger.debug("Asking auth for: " + agent + " " + action + " " + entity);
    if (agent == null) agent = AuthConfig.allActors;
    if (action == null) action = AuthConfig.allActions;
    if (entity == null) entity = AuthConfig.allEntities;

    if (myAuthServer.contains(agent, action, entity)
        || myAuthServer.contains(agent, action, AuthConfig.allEntities)
        || myAuthServer.contains(agent, AuthConfig.allActions, entity)
        || myAuthServer.contains(agent, AuthConfig.allActions, AuthConfig.allEntities)
        || myAuthServer.contains(AuthConfig.allActors, action, entity)
        || myAuthServer.contains(AuthConfig.allActors, action, AuthConfig.allEntities)
        || myAuthServer.contains(AuthConfig.allActors, AuthConfig.allActions, entity)
        || myAuthServer.contains(
            AuthConfig.allActors, AuthConfig.allActions, AuthConfig.allEntities)) {

      Loggers.authLogger.debug("Granted");
      return true;

    } else {
      if (entity.equals(AuthConfig.allEntities)) return false;
      boolean answer = false;
      Set<TerminologySet> containers;
      if (myFactory.terminologyIndividualExist(entity)) {
        TerminologyIndividual myInd = myFactory.getUncheckedTerminologyIndividual(entity);
        containers = myInd.getContainers(myInd.getLastVersion());
      } else if (myFactory.terminologySetExist(entity)) {
        TerminologySet mySet = myFactory.getUncheckedTerminologySet(entity);
        containers = mySet.getContainers(mySet.getLastVersion());
      } else throw new RegistryAccessException("Unknown: " + entity);
      Iterator<TerminologySet> contIter = containers.iterator();
      while (contIter.hasNext()) {
        TerminologySet parent = contIter.next();
        Loggers.authLogger.trace("Asking up: " + parent.getURI());
        answer = answer || can(agent, action, parent.getURI());
      }
      return answer;
    }
  }
  public String render(
      TerminologyEntity e,
      String version,
      int level,
      String language,
      String baseURL,
      CacheManager cacheManager,
      LabelManager lm,
      BackgroundKnowledgeManager bkm,
      String registryBaseURL,
      String tag)
      throws ModelException {
    if (e.isVersioned() && (!printIfVersioned)) return "";
    if (!e.isVersioned() && (!printIfUnVersioned)) return "";
    String resultString = rawString;
    String label = e.getLabel(version, language);
    // if(label==null) label=e.getLabel(version, CoreConfig.DEFAULT_LANGUAGE);
    // if(label==null) label="No label for "+e.getURI();
    resultString =
        resultString.replace(
            "<<tmtLabel>>", AdvancedClassLabelExtractor.getLabelFor(e, version, language, lm));
    resultString = resultString.replace("<<tmtVersion>>", version);
    String description =
        e.getGenericVersionSpecificStringValueObjectByLanguage(
            MetaLanguage.commentProperty, version, language);
    if (description == null)
      description =
          e.getGenericVersionSpecificStringValueObjectByLanguage(
              MetaLanguage.commentProperty, version, CoreConfig.DEFAULT_LANGUAGE);
    if (description == null) description = "";

    Set<Resource> typesSet =
        e.getGenericVersionSpecificURIObjects(MetaLanguage.typeProperty, version);
    String types = "";
    for (Resource type : typesSet) {
      types +=
          " "
              + lm.getLabelForURI(
                  type.getURI(),
                  language,
                  LabelManager.LANG_DEF_SHORTURI); // TODO needs better separator management
    }
    resultString = resultString.replace("<<tmtDescription>>", description);
    // rawString.replaceAll("<<tmtAuthors>>", replacement);
    resultString = resultString.replace("<<tmtTypes>>", types);
    resultString = resultString.replace("<<tmtURI>>", e.getURI());
    String code =
        e.getGenericVersionSpecificStringValueObject(MetaLanguage.notationProperty, version);
    if (code == null) code = e.getResource().getLocalName();
    resultString = resultString.replace("<<tmtCode>>", code);

    String stem = "";
    if (e.isSet()) stem = PublisherConfig.setStemString;
    if (e.isIndividual()) stem = PublisherConfig.individualStemString;
    // TODO note below we have nulls for docs, but this is not an issue (as far as we don't use the
    // links)
    resultString =
        resultString.replace(
            "<<tmtRDFLink>>",
            cacheManager.getValueFor(e.getURI(), PublisherConfig.uriHasUrl) + "/" + stem + ".rdf");
    resultString =
        resultString.replace(
            "<<tmtTurtleLink>>",
            cacheManager.getValueFor(e.getURI(), PublisherConfig.uriHasUrl) + "/" + stem + ".ttl");

    String statusStr = null;
    if (e.getStateURI(version) != null)
      statusStr = lm.getLabelForURI(e.getStateURI(version), language, lm.LANG_DEF_URI);
    if (statusStr == null)
      statusStr = WebRendererStrings.getValueFor(WebRendererStrings.UNDEFINED, language);
    resultString = resultString.replace("<<tmtStatus>>", statusStr);

    String ownerStr = "";
    if (e.getOwnerURI() != null)
      ownerStr = lm.getLabelForURI(e.getOwnerURI(), language, lm.LANG_DEF_URI);

    resultString = resultString.replace("<<tmtOwner>>", ownerStr);

    resultString = resultString.replace("<<tmtLastUpdate>>", e.getLastUpdateDate());
    resultString = resultString.replace("<<tmtGenerationDate>>", e.getGenerationDate());
    Loggers.publishLogger.trace("Entity URI : " + e.getURI());
    Loggers.publishLogger.trace("Version :" + version);
    resultString = resultString.replace("<<tmtActionDate>>", e.getActionDate(version));

    String versionStr = version;

    // TODO the dependency on webRendererString should at this point be eliminated (or at least
    // re-defined).
    if (e.isLastVersion(version)) {
      versionStr +=
          " ("
              + WebRendererStrings.getValueFor(WebRendererStrings.IS_LATEST_VERSION, language)
              + ")";
    } else
      versionStr +=
          " ("
              + WebRendererStrings.getValueFor(WebRendererStrings.HAS_LATEST_VERSION, language)
              + " <a href=\""
              + cacheManager.getValueFor(e.getURI(), PublisherConfig.uriHasUrl)
              + "/"
              + e.getLastVersion()
              + "\">"
              + e.getLastVersion()
              + "</a>)";
    resultString = resultString.replace("<<tmtNewerVersion>>", versionStr);

    Iterator<TerminologySet> containers = e.getContainers(version).iterator();
    String containerURL = "";
    String containerLabel = "";
    // TODO Note that the cache may not be prsent for -doc exports
    if (containers
        .hasNext()) { // TODO note that we expect only one container! This maybe should be made
                      // implicit by design, or this template should be changed.
      TerminologySet container = containers.next();
      containerURL = cacheManager.getValueFor(container.getURI(), PublisherConfig.uriHasUrl);
      containerLabel = container.getLabel(container.getLastVersion(), language);
    }

    if (containerURL != null) resultString = resultString.replace("<<tmtFatherURL>>", containerURL);
    if (containerLabel != null)
      resultString = resultString.replace("<<tmtFatherLabel>>", containerLabel);

    return resultString;
  }