ippAddStrings(
    ipp_t              *ipp,		/* I - IPP message */
    ipp_tag_t          group,		/* I - IPP group */
    ipp_tag_t          value_tag,	/* I - Type of attribute */
    const char         *name,		/* I - Name of attribute */
    int                num_values,	/* I - Number of values */
    const char         *language,	/* I - Language code (@code NULL@ for default) */
    const char * const *values)		/* I - Values */
{
  int			i;		/* Looping var */
  ipp_tag_t		temp_tag;	/* Temporary value tag (masked) */
  ipp_attribute_t	*attr;		/* New attribute */
  _ipp_value_t		*value;		/* Current value */
  char			code[32];	/* Language/charset value buffer */


  DEBUG_printf(("ippAddStrings(ipp=%p, group=%02x(%s), value_tag=%02x(%s), name=\"%s\", num_values=%d, language=\"%s\", values=%p)", (void *)ipp, group, ippTagString(group), value_tag, ippTagString(value_tag), name, num_values, language, (void *)values));

 /*
  * Range check input...
  */

  temp_tag = (ipp_tag_t)((int)value_tag & IPP_TAG_CUPS_MASK);

#if 0
  if (!ipp || !name || group < IPP_TAG_ZERO ||
      group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
      (temp_tag < IPP_TAG_TEXT && temp_tag != IPP_TAG_TEXTLANG &&
       temp_tag != IPP_TAG_NAMELANG) || temp_tag > IPP_TAG_MIMETYPE ||
      num_values < 1)
    return (NULL);

  if ((temp_tag == IPP_TAG_TEXTLANG || temp_tag == IPP_TAG_NAMELANG)
          != (language != NULL))
    return (NULL);
#else
  if (!ipp || !name || group < IPP_TAG_ZERO ||
      group == IPP_TAG_END || group >= IPP_TAG_UNSUPPORTED_VALUE ||
      num_values < 1)
    return (NULL);
#endif /* 0 */

 /*
  * See if we need to map charset, language, or locale values...
  */

  if (language && ((int)value_tag & IPP_TAG_CUPS_CONST) &&
      strcmp(language, ipp_lang_code(language, code, sizeof(code))))
    value_tag = temp_tag;		/* Don't do a fast copy */
  else if (values && value_tag == (ipp_tag_t)(IPP_TAG_CHARSET | IPP_TAG_CUPS_CONST))
  {
    for (i = 0; i < num_values; i ++)
      if (strcmp(values[i], ipp_get_code(values[i], code, sizeof(code))))
      {
	value_tag = temp_tag;		/* Don't do a fast copy */
        break;
      }
  }
  else if (values && value_tag == (ipp_tag_t)(IPP_TAG_LANGUAGE | IPP_TAG_CUPS_CONST))
  {
    for (i = 0; i < num_values; i ++)
      if (strcmp(values[i], ipp_lang_code(values[i], code, sizeof(code))))
      {
	value_tag = temp_tag;		/* Don't do a fast copy */
        break;
      }
  }

 /*
  * Create the attribute...
  */

  if ((attr = ipp_add_attr(ipp, name, group, value_tag, num_values)) == NULL)
    return (NULL);

 /*
  * Initialize the attribute data...
  */

  for (i = num_values, value = attr->values;
       i > 0;
       i --, value ++)
  {
    if (language)
    {
      if (value == attr->values)
      {
        if ((int)value_tag & IPP_TAG_CUPS_CONST)
          value->string.language = (char *)language;
        else
          value->string.language = _cupsStrAlloc(ipp_lang_code(language, code,
                                                               sizeof(code)));
      }
      else
	value->string.language = attr->values[0].string.language;
    }

    if (values)
    {
      if ((int)value_tag & IPP_TAG_CUPS_CONST)
        value->string.text = (char *)*values++;
      else if (value_tag == IPP_TAG_CHARSET)
	value->string.text = _cupsStrAlloc(ipp_get_code(*values++, code, sizeof(code)));
      else if (value_tag == IPP_TAG_LANGUAGE)
	value->string.text = _cupsStrAlloc(ipp_lang_code(*values++, code, sizeof(code)));
      else
	value->string.text = _cupsStrAlloc(*values++);
    }
  }

  return (attr);
}