if ( ! AbstractQueryImpl.class.isInstance( query ) ) {
      throw new IllegalStateException( "Unknown query type for parameter extraction" );
    }
    HashSet<Parameter<?>> parameters = new HashSet<Parameter<?>>();
    AbstractQueryImpl queryImpl = AbstractQueryImpl.class.cast( query );
    // extract named params
    for ( String name : (Set<String>) queryImpl.getParameterMetadata().getNamedParameterNames() ) {
      final NamedParameterDescriptor descriptor =
          queryImpl.getParameterMetadata().getNamedParameterDescriptor( name );
      Class javaType = namedParameterTypeRedefinition.get( name );
      if ( javaType != null && mightNeedRedefinition( javaType ) ) {
        descriptor.resetExpectedType(
            sfi().getTypeResolver().heuristicType( javaType.getName() )
        );
      }
      else if ( descriptor.getExpectedType() != null ) {
        javaType = descriptor.getExpectedType().getReturnedClass();
      }
      final ParameterImpl parameter = new ParameterImpl( name, javaType );
      parameters.add( parameter );
      if ( descriptor.isJpaStyle() ) {
        if ( jpaPositionalIndices == null ) {
          jpaPositionalIndices = new HashSet<Integer>();
        }
        jpaPositionalIndices.add( Integer.valueOf( name ) );
      }
    }
    // extract positional parameters
    for ( int i = 0, max = queryImpl.getParameterMetadata().getOrdinalParameterCount(); i < max; i++ ) {
      final OrdinalParameterDescriptor descriptor =
          queryImpl.getParameterMetadata().getOrdinalParameterDescriptor( i+1 );
      ParameterImpl parameter = new ParameterImpl(
          i + 1,
          descriptor.getExpectedType() == null
              ? null
              : descriptor.getExpectedType().getReturnedClass()