IN_SKEY",  //28;
        null,
        "RENEW",            //30;
        "VALIDATE",         //31;
    };

    private boolean DEBUG = Krb5.DEBUG;

    public static KDCOptions with(int... flags) {
        KDCOptions options = new KDCOptions();
        for (int flag: flags) {
            options.set(flag, true);
        }
        return options;
    }

    public KDCOptions() {
        super(Krb5.KDC_OPTS_MAX + 1);
        setDefault();
    }

    public KDCOptions(int size, byte[] data) throws Asn1Exception {
        super(size, data);
        if ((size > data.length * BITS_PER_UNIT) || (size > Krb5.KDC_OPTS_MAX + 1))
            throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
    }

    /**
     * Constructs a KDCOptions from the specified bit settings.
     *
     * @param data the bits to be set for the KDCOptions.
     * @exception Asn1Exception if an error occurs while decoding an ASN1
     * encoded data.
     *
     */
    public KDCOptions(boolean[] data) throws Asn1Exception {
        super(data);
        if (data.length > Krb5.KDC_OPTS_MAX + 1) {
            throw new Asn1Exception(Krb5.BITSTRING_BAD_LENGTH);
        }
    }

    public KDCOptions(DerValue encoding) throws Asn1Exception, IOException {
        this(encoding.getUnalignedBitString(true).toBooleanArray());
    }

    /**
     * Constructs a KDCOptions from the passed bit settings.
     *
     * @param options the bits to be set for the KDCOptions.
     *
     */
    public KDCOptions(byte[] options) {
        super(options.length * BITS_PER_UNIT, options);
    }

    /**
     * Parse (unmarshal) a KDCOptions from a DER input stream.  This form
     * parsing might be used when expanding a value which is part of
     * a constructed sequence and uses explicitly tagged type.
     *
     * @param data the Der input stream value, which contains one or more
     * marshaled value.
     * @param explicitTag tag number.
     * @param optional indicate if this data field is optional
     * @return an instance of KDCOptions.
     * @exception A