/*======================================================================
 FILE: vcardderivedparameter.c
 CREATOR: Ken Murchison 24 Aug 2022 <murch@fastmailteam.com>

 SPDX-FileCopyrightText: 2022, Fastmail Pty. Ltd. (https://fastmail.com)
 SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
 ======================================================================*/

/**
 * @file vcardderivedparameter.c
 * @brief vCard parameters.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "vcardderivedparameter.h"
#include "vcardderivedvalue.h"
#include "vcardparameter.h"
#include "vcardparameterimpl.h"
#include "vcardenumarray.h"
#include "vcardstrarray.h"
#include "icalerror_p.h"
#include "icalmemory.h"

#include <stdlib.h>
#include <string.h>

struct vcardparameter_impl *vcardparameter_new_impl(vcardparameter_kind kind);

/* This map associates each of the parameters with the string
   representation of the parameter's name */
struct vcardparameter_kind_map
{
    vcardparameter_kind kind;
    const char *name;

    vcardvalue_kind value_kind;
    unsigned int flags;
};

#define VCARD_PARAMETER_IS_MULTIVALUED (1U<<0)
#define VCARD_PARAMETER_IS_STRUCTURED  (1U<<1)

/* This map associates the enumerations for the VALUE parameter with
   the kinds of VALUEs. */

struct vcardparameter_value_kind_map
{
    vcardparameter_value value;
    vcardvalue_kind kind;
};

/* This map associates the parameter enumerations with a specific parameter
   and the string representation of the enumeration */

struct vcardparameter_map
{
    vcardparameter_kind kind;
    int enumeration;
    const char *str;
};

/* START of section of machine generated code (mkderivedparameters.pl). Do not edit. */

static const struct vcardparameter_value_kind_map value_kind_map[15] = {
    {VCARD_VALUE_TEXT, VCARD_TEXT_VALUE},
    {VCARD_VALUE_URI, VCARD_URI_VALUE},
    {VCARD_VALUE_DATE, VCARD_DATE_VALUE},
    {VCARD_VALUE_TIME, VCARD_TIME_VALUE},
    {VCARD_VALUE_DATETIME, VCARD_DATETIME_VALUE},
    {VCARD_VALUE_DATEANDORTIME, VCARD_DATEANDORTIME_VALUE},
    {VCARD_VALUE_TIMESTAMP, VCARD_TIMESTAMP_VALUE},
    {VCARD_VALUE_BOOLEAN, VCARD_BOOLEAN_VALUE},
    {VCARD_VALUE_INTEGER, VCARD_INTEGER_VALUE},
    {VCARD_VALUE_FLOAT, VCARD_FLOAT_VALUE},
    {VCARD_VALUE_UTCOFFSET, VCARD_UTCOFFSET_VALUE},
    {VCARD_VALUE_LANGUAGETAG, VCARD_LANGUAGETAG_VALUE},
    {VCARD_VALUE_STRUCTURED, VCARD_STRUCTURED_VALUE},
    {VCARD_VALUE_X, VCARD_X_VALUE},
    {VCARD_VALUE_NONE, VCARD_NO_VALUE}
};

static const struct vcardparameter_kind_map parameter_map[33] = {
    {VCARD_ALTID_PARAMETER, "ALTID", VCARD_TEXT_VALUE, 0},
    {VCARD_AUTHOR_PARAMETER, "AUTHOR", VCARD_TEXT_VALUE, 0},
    {VCARD_AUTHORNAME_PARAMETER, "AUTHOR-NAME", VCARD_TEXT_VALUE, 0},
    {VCARD_CALSCALE_PARAMETER, "CALSCALE", VCARD_X_VALUE, 0},
    {VCARD_CC_PARAMETER, "CC", VCARD_TEXT_VALUE, 0},
    {VCARD_CONTEXT_PARAMETER, "CONTEXT", VCARD_TEXT_VALUE, 0},
    {VCARD_CREATED_PARAMETER, "CREATED", VCARD_DATEANDORTIME_VALUE, 0},
    {VCARD_DERIVED_PARAMETER, "DERIVED", VCARD_X_VALUE, 0},
    {VCARD_ENCODING_PARAMETER, "ENCODING", VCARD_X_VALUE, 0},
    {VCARD_GEO_PARAMETER, "GEO", VCARD_TEXT_VALUE, 0},
    {VCARD_IANA_PARAMETER, "IANA", VCARD_TEXT_VALUE, 0},
    {VCARD_INDEX_PARAMETER, "INDEX", VCARD_INTEGER_VALUE, 0},
    {VCARD_JSCOMPS_PARAMETER, "JSCOMPS", VCARD_STRUCTURED_VALUE, VCARD_PARAMETER_IS_STRUCTURED},
    {VCARD_JSPTR_PARAMETER, "JSPTR", VCARD_TEXT_VALUE, 0},
    {VCARD_LABEL_PARAMETER, "LABEL", VCARD_TEXT_VALUE, 0},
    {VCARD_LANGUAGE_PARAMETER, "LANGUAGE", VCARD_TEXT_VALUE, 0},
    {VCARD_LEVEL_PARAMETER, "LEVEL", VCARD_X_VALUE, 0},
    {VCARD_MEDIATYPE_PARAMETER, "MEDIATYPE", VCARD_TEXT_VALUE, 0},
    {VCARD_PHONETIC_PARAMETER, "PHONETIC", VCARD_X_VALUE, 0},
    {VCARD_PID_PARAMETER, "PID", VCARD_TEXT_VALUE, VCARD_PARAMETER_IS_MULTIVALUED},
    {VCARD_PREF_PARAMETER, "PREF", VCARD_INTEGER_VALUE, 0},
    {VCARD_PROPID_PARAMETER, "PROP-ID", VCARD_TEXT_VALUE, 0},
    {VCARD_SCRIPT_PARAMETER, "SCRIPT", VCARD_TEXT_VALUE, 0},
    {VCARD_SERVICETYPE_PARAMETER, "SERVICE-TYPE", VCARD_TEXT_VALUE, 0},
    {VCARD_SORTAS_PARAMETER, "SORT-AS", VCARD_TEXT_VALUE, VCARD_PARAMETER_IS_MULTIVALUED},
    {VCARD_TYPE_PARAMETER, "TYPE", VCARD_X_VALUE, VCARD_PARAMETER_IS_MULTIVALUED},
    {VCARD_TZ_PARAMETER, "TZ", VCARD_TEXT_VALUE, 0},
    {VCARD_USERNAME_PARAMETER, "USERNAME", VCARD_TEXT_VALUE, 0},
    {VCARD_VALUE_PARAMETER, "VALUE", VCARD_X_VALUE, 0},
    {VCARD_X_PARAMETER, "X", VCARD_TEXT_VALUE, 0},
    {VCARD_XLICCOMPARETYPE_PARAMETER, "X-LIC-COMPARETYPE", VCARD_X_VALUE, 0},
    {VCARD_XLICERRORTYPE_PARAMETER, "X-LIC-ERRORTYPE", VCARD_X_VALUE, 0},
    { VCARD_NO_PARAMETER, "", VCARD_NO_VALUE, 0}
};

static const struct vcardparameter_map vcardparameter_map[] = {
    {VCARD_ANY_PARAMETER, 0, ""},
    {VCARD_CALSCALE_PARAMETER,VCARD_CALSCALE_GREGORIAN, "GREGORIAN"},
    {VCARD_DERIVED_PARAMETER,VCARD_DERIVED_TRUE, "TRUE"},
    {VCARD_DERIVED_PARAMETER,VCARD_DERIVED_FALSE, "FALSE"},
    {VCARD_ENCODING_PARAMETER,VCARD_ENCODING_B, "B"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_BEGINNER, "BEGINNER"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_AVERAGE, "AVERAGE"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_EXPERT, "EXPERT"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_HIGH, "HIGH"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_MEDIUM, "MEDIUM"},
    {VCARD_LEVEL_PARAMETER,VCARD_LEVEL_LOW, "LOW"},
    {VCARD_PHONETIC_PARAMETER,VCARD_PHONETIC_IPA, "IPA"},
    {VCARD_PHONETIC_PARAMETER,VCARD_PHONETIC_PINY, "PINY"},
    {VCARD_PHONETIC_PARAMETER,VCARD_PHONETIC_JYUT, "JYUT"},
    {VCARD_PHONETIC_PARAMETER,VCARD_PHONETIC_SCRIPT, "SCRIPT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_WORK, "WORK"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_HOME, "HOME"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_TEXT, "TEXT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_VOICE, "VOICE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_FAX, "FAX"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_CELL, "CELL"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_VIDEO, "VIDEO"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_PAGER, "PAGER"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_TEXTPHONE, "TEXTPHONE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_CONTACT, "CONTACT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_ACQUAINTANCE, "ACQUAINTANCE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_FRIEND, "FRIEND"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_MET, "MET"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_COWORKER, "CO-WORKER"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_COLLEAGUE, "COLLEAGUE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_CORESIDENT, "CO-RESIDENT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_NEIGHBOR, "NEIGHBOR"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_CHILD, "CHILD"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_PARENT, "PARENT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_SIBLING, "SIBLING"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_SPOUSE, "SPOUSE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_KIN, "KIN"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_MUSE, "MUSE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_CRUSH, "CRUSH"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_DATE, "DATE"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_SWEETHEART, "SWEETHEART"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_ME, "ME"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_AGENT, "AGENT"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_EMERGENCY, "EMERGENCY"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_PREF, "PREF"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_MAINNUMBER, "MAIN-NUMBER"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_BILLING, "BILLING"},
    {VCARD_TYPE_PARAMETER,VCARD_TYPE_DELIVERY, "DELIVERY"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_TEXT, "TEXT"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_URI, "URI"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_DATE, "DATE"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_TIME, "TIME"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_DATETIME, "DATE-TIME"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_DATEANDORTIME, "DATE-AND-OR-TIME"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_TIMESTAMP, "TIMESTAMP"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_BOOLEAN, "BOOLEAN"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_INTEGER, "INTEGER"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_FLOAT, "FLOAT"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_UTCOFFSET, "UTC-OFFSET"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_LANGUAGETAG, "LANGUAGE-TAG"},
    {VCARD_VALUE_PARAMETER,VCARD_VALUE_STRUCTURED, "STRUCTURED"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_EQUAL, "EQUAL"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_NOTEQUAL, "NOTEQUAL"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_LESS, "LESS"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_GREATER, "GREATER"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_LESSEQUAL, "LESSEQUAL"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_GREATEREQUAL, "GREATEREQUAL"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_REGEX, "REGEX"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_ISNULL, "ISNULL"},
    {VCARD_XLICCOMPARETYPE_PARAMETER,VCARD_XLICCOMPARETYPE_ISNOTNULL, "ISNOTNULL"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_COMPONENTPARSEERROR, "COMPONENT-PARSE-ERROR"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_PROPERTYPARSEERROR, "PROPERTY-PARSE-ERROR"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_PARAMETERNAMEPARSEERROR, "PARAMETER-NAME-PARSE-ERROR"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_PARAMETERVALUEPARSEERROR, "PARAMETER-VALUE-PARSE-ERROR"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_VALUEPARSEERROR, "VALUE-PARSE-ERROR"},
    {VCARD_XLICERRORTYPE_PARAMETER,VCARD_XLICERRORTYPE_RESTRICTIONCHECK, "RESTRICTION-CHECK"},
    {VCARD_NO_PARAMETER, 0, ""}
};


/* ALTID */
vcardparameter *vcardparameter_new_altid(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_ALTID_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_altid((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_altid(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_altid(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* AUTHOR */
vcardparameter *vcardparameter_new_author(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_AUTHOR_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_author((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_author(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_author(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* AUTHOR-NAME */
vcardparameter *vcardparameter_new_authorname(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_AUTHORNAME_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_authorname((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_authorname(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_authorname(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* CALSCALE */
vcardparameter *vcardparameter_new_calscale(vcardparameter_calscale v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_CALSCALE_X, "v");
    icalerror_check_arg_rz(v < VCARD_CALSCALE_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_CALSCALE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_calscale((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_calscale vcardparameter_get_calscale(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_CALSCALE_NONE;
    }
    if (param->string != 0) {
        return VCARD_CALSCALE_X;
    }

    return (vcardparameter_calscale)(param->data);
}

void vcardparameter_set_calscale(vcardparameter *param, vcardparameter_calscale v)
{
    icalerror_check_arg_rv(v >= VCARD_CALSCALE_X, "v");
    icalerror_check_arg_rv(v < VCARD_CALSCALE_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* CC */
vcardparameter *vcardparameter_new_cc(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_CC_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_cc((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_cc(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_cc(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* CONTEXT */
vcardparameter *vcardparameter_new_context(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_CONTEXT_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_context((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_context(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_context(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* CREATED */
vcardparameter *vcardparameter_new_created(vcardtimetype v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();

    impl = vcardparameter_new_impl(VCARD_CREATED_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_created((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardtimetype vcardparameter_get_created(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (param != 0) {
       return param->date;
    } else {
       return vcardtime_null_datetime();
    }
}

void vcardparameter_set_created(vcardparameter *param, vcardtimetype v)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->date = v;
}

/* DERIVED */
vcardparameter *vcardparameter_new_derived(vcardparameter_derived v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_DERIVED_X, "v");
    icalerror_check_arg_rz(v < VCARD_DERIVED_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_DERIVED_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_derived((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_derived vcardparameter_get_derived(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_DERIVED_NONE;
    }
    if (param->string != 0) {
        return VCARD_DERIVED_X;
    }

    return (vcardparameter_derived)(param->data);
}

void vcardparameter_set_derived(vcardparameter *param, vcardparameter_derived v)
{
    icalerror_check_arg_rv(v >= VCARD_DERIVED_X, "v");
    icalerror_check_arg_rv(v < VCARD_DERIVED_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* ENCODING */
vcardparameter *vcardparameter_new_encoding(vcardparameter_encoding v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_ENCODING_X, "v");
    icalerror_check_arg_rz(v < VCARD_ENCODING_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_ENCODING_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_encoding((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_encoding vcardparameter_get_encoding(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_ENCODING_NONE;
    }
    if (param->string != 0) {
        return VCARD_ENCODING_X;
    }

    return (vcardparameter_encoding)(param->data);
}

void vcardparameter_set_encoding(vcardparameter *param, vcardparameter_encoding v)
{
    icalerror_check_arg_rv(v >= VCARD_ENCODING_X, "v");
    icalerror_check_arg_rv(v < VCARD_ENCODING_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* GEO */
vcardparameter *vcardparameter_new_geo(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_GEO_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_geo((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_geo(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_geo(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* IANA */
vcardparameter *vcardparameter_new_iana(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_IANA_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_iana((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_iana(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_iana(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* INDEX */
vcardparameter *vcardparameter_new_index(int v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();

    impl = vcardparameter_new_impl(VCARD_INDEX_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_index((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

int vcardparameter_get_index(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (param != 0) {
       return param->data;
    } else {
       return 0;
    }
}

void vcardparameter_set_index(vcardparameter *param, int v)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = v;
}

/* JSCOMPS */
vcardparameter *vcardparameter_new_jscomps(vcardstructuredtype * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();

    impl = vcardparameter_new_impl(VCARD_JSCOMPS_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_jscomps((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardstructuredtype * vcardparameter_get_jscomps(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->structured;
}

void vcardparameter_set_jscomps(vcardparameter *param, vcardstructuredtype * v)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->structured != NULL) {
        vcardstructured_unref(param->structured);
    }
    vcardstructured_ref(v);
    ((struct vcardparameter_impl *)param)->structured = v;
}

/* JSPTR */
vcardparameter *vcardparameter_new_jsptr(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_JSPTR_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_jsptr((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_jsptr(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_jsptr(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* LABEL */
vcardparameter *vcardparameter_new_label(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_LABEL_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_label((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_label(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_label(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* LANGUAGE */
vcardparameter *vcardparameter_new_language(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_LANGUAGE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_language((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_language(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_language(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* LEVEL */
vcardparameter *vcardparameter_new_level(vcardparameter_level v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_LEVEL_X, "v");
    icalerror_check_arg_rz(v < VCARD_LEVEL_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_LEVEL_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_level((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_level vcardparameter_get_level(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_LEVEL_NONE;
    }
    if (param->string != 0) {
        return VCARD_LEVEL_X;
    }

    return (vcardparameter_level)(param->data);
}

void vcardparameter_set_level(vcardparameter *param, vcardparameter_level v)
{
    icalerror_check_arg_rv(v >= VCARD_LEVEL_X, "v");
    icalerror_check_arg_rv(v < VCARD_LEVEL_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* MEDIATYPE */
vcardparameter *vcardparameter_new_mediatype(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_MEDIATYPE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_mediatype((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_mediatype(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_mediatype(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* PHONETIC */
vcardparameter *vcardparameter_new_phonetic(vcardparameter_phonetic v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_PHONETIC_X, "v");
    icalerror_check_arg_rz(v < VCARD_PHONETIC_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_PHONETIC_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_phonetic((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_phonetic vcardparameter_get_phonetic(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_PHONETIC_NONE;
    }
    if (param->string != 0) {
        return VCARD_PHONETIC_X;
    }

    return (vcardparameter_phonetic)(param->data);
}

void vcardparameter_set_phonetic(vcardparameter *param, vcardparameter_phonetic v)
{
    icalerror_check_arg_rv(v >= VCARD_PHONETIC_X, "v");
    icalerror_check_arg_rv(v < VCARD_PHONETIC_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* PID */
vcardparameter *vcardparameter_new_pid_list(vcardstrarray * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_PID_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_pid((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardstrarray * vcardparameter_get_pid(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->values;
}

void vcardparameter_set_pid(vcardparameter *param, vcardstrarray * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->values != NULL) {
        vcardstrarray_free(param->values);
    }
    ((struct vcardparameter_impl *)param)->values = v;
}

vcardparameter * vcardparameter_new_pid(const char * v)
{
    vcardstrarray *values = vcardstrarray_new(1);
    icalstrarray_add(values, v);
    return vcardparameter_new_pid_list(values);
}

size_t vcardparameter_get_pid_size(vcardparameter *param)
{
    icalerror_check_arg_rz((param != 0), "param");
    if (param->values) {
        return param->values->num_elements;
    }
    return 0;
}

const char * vcardparameter_get_pid_nth(vcardparameter *param, size_t position)
{
    icalerror_check_arg_rz((param != 0), "param");
    if (param->values && vcardstrarray_size(param->values)) {
        return vcardstrarray_element_at(param->values, position);
    } else {
        return NULL;
    }
}

void vcardparameter_add_pid(vcardparameter *param, const char * v)
{vcardstrarray **values;
    
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = &((struct vcardparameter_impl *)param)->values;
    if (*values == 0) {
        *values = vcardstrarray_new(5);
    }
    vcardstrarray_add(*values, v);
}

void vcardparameter_remove_pid(vcardparameter *param, const char * v)
{vcardstrarray *values;
    
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = ((struct vcardparameter_impl *)param)->values;
    if (values != 0) {
        vcardstrarray_remove(values, v);
    }
}


/* PREF */
vcardparameter *vcardparameter_new_pref(int v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();

    impl = vcardparameter_new_impl(VCARD_PREF_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_pref((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

int vcardparameter_get_pref(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (param != 0) {
       return param->data;
    } else {
       return 0;
    }
}

void vcardparameter_set_pref(vcardparameter *param, int v)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = v;
}

/* PROP-ID */
vcardparameter *vcardparameter_new_propid(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_PROPID_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_propid((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_propid(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_propid(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* SCRIPT */
vcardparameter *vcardparameter_new_script(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_SCRIPT_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_script((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_script(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_script(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* SERVICE-TYPE */
vcardparameter *vcardparameter_new_servicetype(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_SERVICETYPE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_servicetype((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_servicetype(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_servicetype(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* SORT-AS */
vcardparameter *vcardparameter_new_sortas_list(vcardstrarray * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_SORTAS_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_sortas((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardstrarray * vcardparameter_get_sortas(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->values;
}

void vcardparameter_set_sortas(vcardparameter *param, vcardstrarray * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->values != NULL) {
        vcardstrarray_free(param->values);
    }
    ((struct vcardparameter_impl *)param)->values = v;
}

vcardparameter * vcardparameter_new_sortas(const char * v)
{
    vcardstrarray *values = vcardstrarray_new(1);
    icalstrarray_add(values, v);
    return vcardparameter_new_sortas_list(values);
}

size_t vcardparameter_get_sortas_size(vcardparameter *param)
{
    icalerror_check_arg_rz((param != 0), "param");
    if (param->values) {
        return param->values->num_elements;
    }
    return 0;
}

const char * vcardparameter_get_sortas_nth(vcardparameter *param, size_t position)
{
    icalerror_check_arg_rz((param != 0), "param");
    if (param->values && vcardstrarray_size(param->values)) {
        return vcardstrarray_element_at(param->values, position);
    } else {
        return NULL;
    }
}

void vcardparameter_add_sortas(vcardparameter *param, const char * v)
{vcardstrarray **values;
    
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = &((struct vcardparameter_impl *)param)->values;
    if (*values == 0) {
        *values = vcardstrarray_new(5);
    }
    vcardstrarray_add(*values, v);
}

void vcardparameter_remove_sortas(vcardparameter *param, const char * v)
{vcardstrarray *values;
    
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = ((struct vcardparameter_impl *)param)->values;
    if (values != 0) {
        vcardstrarray_remove(values, v);
    }
}


/* TYPE */
vcardparameter *vcardparameter_new_type_list(vcardenumarray * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();

    impl = vcardparameter_new_impl(VCARD_TYPE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_type((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardenumarray * vcardparameter_get_type(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->values;
}

void vcardparameter_set_type(vcardparameter *param, vcardenumarray * v)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->values != NULL) {
        vcardenumarray_free(param->values);
    }
    ((struct vcardparameter_impl *)param)->values = v;
}

vcardparameter * vcardparameter_new_type(vcardparameter_type v)
{
    vcardenumarray *values = vcardenumarray_new(1);
    icalenumarray_element _elem = { (int)v, NULL };
    icalenumarray_add(values, &_elem);
    return vcardparameter_new_type_list(values);
}

size_t vcardparameter_get_type_size(vcardparameter *param)
{
    icalerror_check_arg_rz((param != 0), "param");
    if (param->values) {
        return param->values->num_elements;
    }
    return 0;
}

vcardparameter_type vcardparameter_get_type_nth(vcardparameter *param, size_t position)
{
    icalerror_check_arg((param != 0), "param");
    if (param && param->values && vcardenumarray_size(param->values)) {
        const vcardenumarray_element * v = vcardenumarray_element_at(param->values, position);
        return (vcardparameter_type)v->val;
    } else {
        return VCARD_TYPE_NONE;
    }
}

void vcardparameter_add_type(vcardparameter *param, vcardenumarray_element * v)
{vcardenumarray **values;
    
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = &((struct vcardparameter_impl *)param)->values;
    if (*values == 0) {
        *values = vcardenumarray_new(5);
    }
    vcardenumarray_add(*values, v);
}

void vcardparameter_remove_type(vcardparameter *param, vcardenumarray_element * v)
{vcardenumarray *values;
    
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    values = ((struct vcardparameter_impl *)param)->values;
    if (values != 0) {
        vcardenumarray_remove(values, v);
    }
}


/* TZ */
vcardparameter *vcardparameter_new_tz(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_TZ_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_tz((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_tz(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_tz(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* USERNAME */
vcardparameter *vcardparameter_new_username(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_USERNAME_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_username((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_username(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_username(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* VALUE */
vcardparameter *vcardparameter_new_value(vcardparameter_value v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_VALUE_X, "v");
    icalerror_check_arg_rz(v < VCARD_VALUE_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_VALUE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_value((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_value vcardparameter_get_value(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_VALUE_NONE;
    }
    if (param->string != 0) {
        return VCARD_VALUE_X;
    }

    return (vcardparameter_value)(param->data);
}

void vcardparameter_set_value(vcardparameter *param, vcardparameter_value v)
{
    icalerror_check_arg_rv(v >= VCARD_VALUE_X, "v");
    icalerror_check_arg_rv(v < VCARD_VALUE_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* X */
vcardparameter *vcardparameter_new_x(const char * v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz((v != 0), "v");
    impl = vcardparameter_new_impl(VCARD_X_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_x((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

const char * vcardparameter_get_x(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg_rz((param != 0), "param");
    return param->string;
}

void vcardparameter_set_x(vcardparameter *param, const char * v)
{
    icalerror_check_arg_rv((v != 0), "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    if (param->string != NULL) {
        icalmemory_free_buffer((void *)param->string);
    }
    ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(v);
}

/* X-LIC-COMPARETYPE */
vcardparameter *vcardparameter_new_xliccomparetype(vcardparameter_xliccomparetype v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_XLICCOMPARETYPE_X, "v");
    icalerror_check_arg_rz(v < VCARD_XLICCOMPARETYPE_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_XLICCOMPARETYPE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_xliccomparetype((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_xliccomparetype vcardparameter_get_xliccomparetype(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_XLICCOMPARETYPE_NONE;
    }

    return (vcardparameter_xliccomparetype)(param->data);
}

void vcardparameter_set_xliccomparetype(vcardparameter *param, vcardparameter_xliccomparetype v)
{
    icalerror_check_arg_rv(v >= VCARD_XLICCOMPARETYPE_X, "v");
    icalerror_check_arg_rv(v < VCARD_XLICCOMPARETYPE_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}

/* X-LIC-ERRORTYPE */
vcardparameter *vcardparameter_new_xlicerrortype(vcardparameter_xlicerrortype v)
{
    struct vcardparameter_impl *impl;
    icalerror_clear_errno();
    icalerror_check_arg_rz(v >= VCARD_XLICERRORTYPE_X, "v");
    icalerror_check_arg_rz(v < VCARD_XLICERRORTYPE_NONE, "v");
    impl = vcardparameter_new_impl(VCARD_XLICERRORTYPE_PARAMETER);
    if (impl == 0) {
       return 0;
    }

    vcardparameter_set_xlicerrortype((vcardparameter *)impl, v);
    if (icalerrno != ICAL_NO_ERROR) {
       vcardparameter_free((vcardparameter *)impl);
       return 0;
    }

    return (vcardparameter *)impl;
}

vcardparameter_xlicerrortype vcardparameter_get_xlicerrortype(const vcardparameter *param)
{
    icalerror_clear_errno();
    icalerror_check_arg((param != 0), "param");
    if (!param) {
        return VCARD_XLICERRORTYPE_NONE;
    }

    return (vcardparameter_xlicerrortype)(param->data);
}

void vcardparameter_set_xlicerrortype(vcardparameter *param, vcardparameter_xlicerrortype v)
{
    icalerror_check_arg_rv(v >= VCARD_XLICERRORTYPE_X, "v");
    icalerror_check_arg_rv(v < VCARD_XLICERRORTYPE_NONE, "v");
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_clear_errno();

    ((struct vcardparameter_impl *)param)->data = (int)v;
}
/* END   of section of machine generated code (mkderivedparameters.pl). Do not edit. */


vcardvalue_kind vcardparameter_kind_value_kind(const vcardparameter_kind kind,
                                               int *is_multivalued)
{
    int i, num_params;

    num_params = (int)(sizeof(parameter_map) / sizeof(parameter_map[0]));
    for (i = 0; i < num_params; i++) {
        if (parameter_map[i].kind == kind) {
            if (is_multivalued) {
                *is_multivalued =
                    (parameter_map[i].flags & VCARD_PARAMETER_IS_MULTIVALUED);
            }
            return (parameter_map[i].value_kind);
        }
    }

    return 0;
}

bool vcardparameter_kind_is_valid(const vcardparameter_kind kind)
{
    int i = 0;
    int num_params = (int)(sizeof(parameter_map) / sizeof(parameter_map[0]));

    if (kind == VCARD_ANY_PARAMETER) {
        return false;
    }

    num_params--;
    do {
        if (parameter_map[i].kind == kind) {
            return true;
        }
    } while (i++ < num_params);

    return false;
}

const char *vcardparameter_kind_to_string(vcardparameter_kind kind)
{
    int i, num_params;

    num_params = (int)(sizeof(parameter_map) / sizeof(parameter_map[0]));
    for (i = 0; i < num_params; i++) {
        if (parameter_map[i].kind == kind) {
            return parameter_map[i].name;
        }
    }

    return 0;
}

int vcardparameter_compare_kind_map(const struct vcardparameter_kind_map *a,
                                   const struct vcardparameter_kind_map *b)
{
    return strcasecmp(a->name, b->name);
}

vcardparameter_kind vcardparameter_string_to_kind(const char *string)
{
    struct vcardparameter_kind_map key = {0};
    struct vcardparameter_kind_map *result;

    if (string == 0) {
        return VCARD_NO_PARAMETER;
    }

    key.kind = VCARD_ANY_PARAMETER;
    key.name = string;
    result =
        (struct vcardparameter_kind_map *)bsearch(&key, parameter_map, sizeof(parameter_map) / sizeof(struct vcardparameter_kind_map),
                sizeof(struct vcardparameter_kind_map),
                (int (*)(const void *, const void *))vcardparameter_compare_kind_map);

    if (result) {
        return result->kind;
    }

    if (strncmp(string, "X-", 2) == 0) {
        return VCARD_X_PARAMETER;
    }

//    if (ical_get_unknown_token_handling_setting() == ICAL_TREAT_AS_ERROR) {
    if (0 ) {
        return VCARD_NO_PARAMETER;
    } else {
        return VCARD_IANA_PARAMETER;
    }
}

vcardvalue_kind vcardparameter_value_to_value_kind(vcardparameter_value value)
{
    int i;

    for (i = 0; value_kind_map[i].kind != VCARD_NO_VALUE; i++) {

        if (value_kind_map[i].value == value) {
            return value_kind_map[i].kind;
        }
    }

    return VCARD_NO_VALUE;
}

const char *vcardparameter_enum_to_string(int e)
{
    int i, num_params;

    icalerror_check_arg_rz(e >= VCARDPARAMETER_FIRST_ENUM, "e");
    icalerror_check_arg_rz(e <= VCARDPARAMETER_LAST_ENUM, "e");

    num_params = (int)(sizeof(vcardparameter_map) / sizeof(vcardparameter_map[0]));
    for (i = 0; i < num_params; i++) {
        if (e == vcardparameter_map[i].enumeration) {
            return vcardparameter_map[i].str;
        }
    }

    return 0;
}

int _vcardparameter_string_to_enum(const char *str, vcardparameter_kind kind)
{
    int i, num_params;

    icalerror_check_arg_rz(str != 0, "str");

    num_params = (int)(sizeof(vcardparameter_map) / sizeof(vcardparameter_map[0]));
    for (i = 0; i < num_params; i++) {
        if (kind == VCARD_ANY_PARAMETER || (kind == vcardparameter_map[i].kind)) {
            if (strcasecmp(str, vcardparameter_map[i].str) == 0) {
                return vcardparameter_map[i].enumeration;
            }
        }
    }

    return 0;
}

int vcardparameter_string_to_enum(const char *str)
{
    return _vcardparameter_string_to_enum(str, VCARD_ANY_PARAMETER);
}

void vcardparameter_set_value_from_string(vcardparameter *param,
                                          const char *val)
{
    icalerror_check_arg_rv((param != 0), "param");
    icalerror_check_arg_rv((val != 0), "val");

    if (param->value_kind == VCARD_INTEGER_VALUE) {
        param->data = atoi(val);

    } else if (param->value_kind == VCARD_DATEANDORTIME_VALUE) {
        ((struct vcardparameter_impl *)param)->date = vcardtime_from_string(val, 0);

    } else if (param->value_kind == VCARD_TEXT_VALUE) {
        ((struct vcardparameter_impl *)param)->string = icalmemory_strdup(val);

    } else if (param->value_kind == VCARD_STRUCTURED_VALUE) {
        ((struct vcardparameter_impl *)param)->structured =
            vcardstructured_new_from_string(val);

    } else {
        /* Search through the parameter map to find a matching kind */
        int enumeration = _vcardparameter_string_to_enum(val, param->kind);

        if (enumeration != 0) {
            param->data = enumeration;

        } else {
            /* The kind was in the parameter map, but the string did not
               match, so assume that it is an alternate value, like an
               X-value. */

            vcardparameter_set_xvalue(param, val);
        }
    }
}

void vcardparameter_add_value_from_string(vcardparameter *param,
                                          const char *val)
{
    icalerror_check_arg_rv((param != 0 && param->is_multivalued != 0), "param");
    icalerror_check_arg_rv((val != 0), "val");

    if (param->value_kind == VCARD_TEXT_VALUE) {
        if (param->values == 0) {
            param->values = vcardstrarray_new(5);
        }

        vcardstrarray_add(param->values, val);

    } else {
        /* Search through the parameter map to find a matching kind */
        int enumeration = _vcardparameter_string_to_enum(val, param->kind);
        vcardenumarray_element e = { enumeration, NULL };

        if (enumeration == 0) {
            /* The kind was in the parameter map, but the string did not
               match, so assume that it is an alternate value, like an
               X-value. */
            e.xvalue = (char *) val;
        }

        if (param->values == 0) {
            param->values = vcardenumarray_new(5);
        }

        vcardenumarray_add(param->values, &e);
    }
}

vcardparameter *vcardparameter_new_from_value_string(vcardparameter_kind kind,
                                                     const char *val)
{
    struct vcardparameter_impl *param = 0;

    icalerror_check_arg_rz((val != 0), "val");

    param = vcardparameter_new_impl(kind);
    if (!param) {
        return 0;
    }

    vcardparameter_set_value_from_string(param, val);

    return param;
}
