@Override
  @DB
  public long addTemplateToZone(VMTemplateVO tmplt, long zoneId) {
    Transaction txn = Transaction.currentTxn();
    txn.start();
    VMTemplateVO tmplt2 = findById(tmplt.getId());
    if (tmplt2 == null) {
      if (persist(tmplt) == null) {
        throw new CloudRuntimeException("Failed to persist the template " + tmplt);
      }
      if (tmplt.getDetails() != null) {
        _templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails());
      }
    }
    VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
    if (tmpltZoneVO == null) {
      tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date());
      _templateZoneDao.persist(tmpltZoneVO);
    } else {
      tmpltZoneVO.setRemoved(null);
      tmpltZoneVO.setLastUpdated(new Date());
      _templateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO);
    }
    txn.commit();

    return tmplt.getId();
  }
  @Override
  public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
    boolean result = super.configure(name, params);

    PublicSearch = createSearchBuilder();
    PublicSearch.and("public", PublicSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);

    routerTmpltName = (String) params.get("routing.uniquename");

    s_logger.debug("Found parameter routing unique name " + routerTmpltName);
    if (routerTmpltName == null) {
      routerTmpltName = "routing";
    }

    consoleProxyTmpltName = (String) params.get("consoleproxy.uniquename");
    if (consoleProxyTmpltName == null) {
      consoleProxyTmpltName = "routing";
    }
    if (s_logger.isDebugEnabled()) {
      s_logger.debug("Use console proxy template : " + consoleProxyTmpltName);
    }

    UniqueNameSearch = createSearchBuilder();
    UniqueNameSearch.and(
        "uniqueName", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ);
    NameSearch = createSearchBuilder();
    NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);

    NameAccountIdSearch = createSearchBuilder();
    NameAccountIdSearch.and("name", NameAccountIdSearch.entity().getName(), SearchCriteria.Op.EQ);
    NameAccountIdSearch.and(
        "accountId", NameAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);

    PublicIsoSearch = createSearchBuilder();
    PublicIsoSearch.and(
        "public", PublicIsoSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);
    PublicIsoSearch.and("format", PublicIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ);
    PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
    PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ);
    PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ);

    tmpltTypeHyperSearch = createSearchBuilder();
    tmpltTypeHyperSearch.and(
        "templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);
    SearchBuilder<HostVO> hostHyperSearch = _hostDao.createSearchBuilder();
    hostHyperSearch.and("type", hostHyperSearch.entity().getType(), SearchCriteria.Op.EQ);
    hostHyperSearch.and("zoneId", hostHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
    hostHyperSearch.groupBy(hostHyperSearch.entity().getHypervisorType());

    tmpltTypeHyperSearch.join(
        "tmplHyper",
        hostHyperSearch,
        hostHyperSearch.entity().getHypervisorType(),
        tmpltTypeHyperSearch.entity().getHypervisorType(),
        JoinBuilder.JoinType.INNER);
    hostHyperSearch.done();
    tmpltTypeHyperSearch.done();

    tmpltTypeHyperSearch2 = createSearchBuilder();
    tmpltTypeHyperSearch2.and(
        "templateType", tmpltTypeHyperSearch2.entity().getTemplateType(), SearchCriteria.Op.EQ);
    tmpltTypeHyperSearch2.and(
        "hypervisorType", tmpltTypeHyperSearch2.entity().getHypervisorType(), SearchCriteria.Op.EQ);

    tmpltTypeSearch = createSearchBuilder();
    tmpltTypeSearch.and(
        "templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ);

    AccountIdSearch = createSearchBuilder();
    AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
    AccountIdSearch.and(
        "publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ);
    AccountIdSearch.done();

    SearchBuilder<VMTemplateZoneVO> tmpltZoneSearch = _templateZoneDao.createSearchBuilder();
    tmpltZoneSearch.and("removed", tmpltZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
    tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ);

    TmpltsInZoneSearch = createSearchBuilder();
    TmpltsInZoneSearch.and(
        "removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
    TmpltsInZoneSearch.and()
        .op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ);
    TmpltsInZoneSearch.or(
        "templateType", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NULL);
    TmpltsInZoneSearch.cp();
    TmpltsInZoneSearch.join(
        "tmpltzone",
        tmpltZoneSearch,
        tmpltZoneSearch.entity().getTemplateId(),
        TmpltsInZoneSearch.entity().getId(),
        JoinBuilder.JoinType.INNER);
    tmpltZoneSearch.done();
    TmpltsInZoneSearch.done();

    CountTemplatesByAccount = createSearchBuilder(Long.class);
    CountTemplatesByAccount.select(null, Func.COUNT, null);
    CountTemplatesByAccount.and(
        "account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
    CountTemplatesByAccount.and(
        "removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL);
    CountTemplatesByAccount.done();

    return result;
  }