public static void processDynamicFilterParameters(
      final String sqlFragment, final ParameterContainer container, final HqlSqlWalker walker) {
    if (walker.getEnabledFilters().isEmpty()
        && (!hasDynamicFilterParam(sqlFragment))
        && (!(hasCollectionFilterParam(sqlFragment)))) {
      return;
    }

    Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
    String symbols =
        new StringBuffer()
            .append(ParserHelper.HQL_SEPARATORS)
            .append(dialect.openQuote())
            .append(dialect.closeQuote())
            .toString();
    StringTokenizer tokens = new StringTokenizer(sqlFragment, symbols, true);
    StringBuffer result = new StringBuffer();

    while (tokens.hasMoreTokens()) {
      final String token = tokens.nextToken();
      if (token.startsWith(ParserHelper.HQL_VARIABLE_PREFIX)) {
        final String filterParameterName = token.substring(1);
        final String[] parts = LoadQueryInfluencers.parseFilterParameterName(filterParameterName);
        final FilterImpl filter = (FilterImpl) walker.getEnabledFilters().get(parts[0]);
        final Object value = filter.getParameter(parts[1]);
        final Type type = filter.getFilterDefinition().getParameterType(parts[1]);
        final String typeBindFragment =
            StringHelper.join(
                ",",
                ArrayHelper.fillArray(
                    "?", type.getColumnSpan(walker.getSessionFactoryHelper().getFactory())));
        final String bindFragment =
            (value != null && Collection.class.isInstance(value))
                ? StringHelper.join(
                    ",", ArrayHelper.fillArray(typeBindFragment, ((Collection) value).size()))
                : typeBindFragment;
        result.append(bindFragment);
        container.addEmbeddedParameter(
            new DynamicFilterParameterSpecification(parts[0], parts[1], type));
      } else {
        result.append(token);
      }
    }

    container.setText(result.toString());
  }
  /**
   * Add on association (one-to-one, many-to-one, or a collection) to a list of associations to be
   * fetched by outerjoin
   */
  private void addAssociationToJoinTree(
      final AssociationType type,
      final String[] aliasedLhsColumns,
      final String alias,
      final PropertyPath path,
      final int currentDepth,
      final JoinType joinType)
      throws MappingException {

    Joinable joinable = type.getAssociatedJoinable(getFactory());

    // important to generate alias based on size of association collection
    // *before* adding this join to that collection
    String subalias = generateTableAlias(associations.size() + 1, path, joinable);

    // NOTE : it should be fine to continue to pass only filters below
    // (instead of LoadQueryInfluencers) since "from that point on" we
    // only need to worry about restrictions (and not say adding more
    // joins)
    OuterJoinableAssociation assoc =
        new OuterJoinableAssociation(
            path,
            type,
            alias,
            aliasedLhsColumns,
            subalias,
            joinType,
            getWithClause(path),
            hasRestriction(path),
            getFactory(),
            loadQueryInfluencers.getEnabledFilters());
    assoc.validateJoin(path.getFullPath());
    associations.add(assoc);

    int nextDepth = currentDepth + 1;
    //		path = "";
    if (!joinable.isCollection()) {
      if (joinable instanceof OuterJoinLoadable) {
        walkEntityTree((OuterJoinLoadable) joinable, subalias, path, nextDepth);
      }
    } else {
      if (joinable instanceof QueryableCollection) {
        walkCollectionTree((QueryableCollection) joinable, subalias, path, nextDepth);
      }
    }
  }