config-prettyfaces/src/main/java/com/ocpsoft/pretty/faces/url/URLPatternParser.java
public URL getMappedURL(final Object... params)
   {
      URL result = null;
      if (params != null)
      {
         Object[] parameters = params;

         /*
          * Check to see if our parameters were provided as a single List
          */
         if ((params.length == 1) && (params[0] != null) && (params[0] instanceof List<?>))
         {
            List<?> list = (List<?>) params[0];
            if (list.size() == 0)
            {
               parameters = new Object[0];
            }
            else
            {
               parameters = list.toArray(params);
            }
         }
         else if ((params.length == 1) && (params[0] == null))
         {
            parameters = new Object[0];
         }

         /*
          * Assert that we have the proper number of parameters.
          */
         if (getParameterCount() != parameters.length)
         {
            throw new PrettyException("Invalid number of path parameters supplied for pattern: " + originalPattern
                     + ", expected <" + getParameterCount() + ">, but got <" + parameters.length + ">");
         }

         /*
          * Build the result URL
          */
         int paramIndex = 0;
         List<String> resultSegments = new ArrayList<String>();
         for (Segment segment : pathSegments)
         {
            String template = segment.getTemplate();
            Matcher parameterMatcher = Segment.getTemplateMatcher(template);

            StringBuffer sb = new StringBuffer();
            while (parameterMatcher.find())
            {
               /*
                * We need to escape $ and \ because they have a special meaning when 
                * used in Matcher#appendReplacement(). From the docs:
                * 
                * Note that backslashes (\) and dollar signs ($) in the replacement string 
                * may cause the results to be different than if it were being treated as a 
                * literal replacement string. Dollar signs may be treated as references to 
                * captured subsequences as described above, and backslashes are used to 
                * escape literal characters in the replacement string.
                */
               String replacement = parameters[paramIndex].toString()
                        .replace("$", "\\$")
                        .replace("\\", "\\\\");

               parameterMatcher.appendReplacement(sb, replacement);
               paramIndex++;
            }
            parameterMatcher.appendTail(sb);
            resultSegments.add(sb.toString());
         }
         result = new URL(resultSegments, urlPattern.getMetadata());
      }
      else if (getParameterCount() > 0)
      {
         throw new PrettyException("Invalid number of parameters supplied: " + originalPattern + ", expected <"
                  + getParameterCount() + ">, got <0>");
      }

      return result;
   }
public URL getMappedURL(final Object... params)
   {
      URL result = null;
      if (params != null)
      {
         Object[] parameters = params;

         /*
          * Check to see if our parameters were provided as a single List
          */
         if ((params.length == 1) && (params[0] != null) && (params[0] instanceof List<?>))
         {
            List<?> list = (List<?>) params[0];
            if (list.size() == 0)
            {
               parameters = new Object[0];
            }
            else
            {
               parameters = list.toArray(params);
            }
         }
         else if ((params.length == 1) && (params[0] == null))
         {
            parameters = new Object[0];
         }

         /*
          * Assert that we have the proper number of parameters.
          */
         if (getParameterCount() != parameters.length)
         {
            throw new PrettyException("Invalid number of path parameters supplied for pattern: " + originalPattern
                     + ", expected <" + getParameterCount() + ">, but got <" + parameters.length + ">");
         }

         /*
          * Build the result URL
          */
         int paramIndex = 0;
         List<String> resultSegments = new ArrayList<String>();
         for (Segment segment : pathSegments)
         {
            String template = segment.getTemplate();
            Matcher parameterMatcher = Segment.getTemplateMatcher(template);

            StringBuffer sb = new StringBuffer();
            while (parameterMatcher.find())
            {
               /*
                * We need to escape $ and \ because they have a special meaning when 
                * used in Matcher#appendReplacement(). From the docs:
                * 
                * Note that backslashes (\) and dollar signs ($) in the replacement string 
                * may cause the results to be different than if it were being treated as a 
                * literal replacement string. Dollar signs may be treated as references to 
                * captured subsequences as described above, and backslashes are used to 
                * escape literal characters in the replacement string.
                */
               String replacement = parameters[paramIndex].toString()
                        .replace("$", "\\$")
                        .replace("\\", "\\\\");

               parameterMatcher.appendReplacement(sb, replacement);
               paramIndex++;
            }
            parameterMatcher.appendTail(sb);
            resultSegments.add(sb.toString());
         }
         result = new URL(resultSegments, urlPattern.getMetadata());
      }
      else if (getParameterCount() > 0)
      {
         throw new PrettyException("Invalid number of parameters supplied: " + originalPattern + ", expected <"
                  + getParameterCount() + ">, got <0>");
      }

      return result;
   }
URL encoding/decoding is not a concern of this method.

@param params Array of Object parameters, in order, to be substituted for mapping pattern values or el
expressions. This method will call the toString() method on each object provided.
<p>
If only one param is specified and it is an instance of List, the list items will be used as parameters
instead. An empty list or a single null parameter are both treated as if no parameters were specified.
</p>
E.g: getMappedUrl(12,55,"foo","bar") for a pattern of /#{el.one}/#{el.two}/#{el.three}/#{el.four}/ will
return the String: "/12/55/foo/bar/"
@return A URL based on this object's urlPatten, with values substituted for el expressions in the order provided