QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name)
{
    // Set the value of a radio button field. This has the following
    // specific behavior:
    // * If this is a radio button field that has a parent that is
    //   also a radio button field and has no explicit /V, call itself
    //   on the parent
    // * If this is a radio button field with children, set /V to the
    //   given value. Then, for each child, if the child has the
    //   specified value as one of its keys in the /N subdictionary of
    //   its /AP (i.e. its normal appearance stream dictionary), set
    //   /AS to name; otherwise, if /Off is a member, set /AS to /Off.
    // Note that we never turn on /NeedAppearances when setting a
    // radio button field.
    QPDFObjectHandle parent = this->oh.getKey("/Parent");
    if (parent.isDictionary() && parent.getKey("/Parent").isNull())
    {
        QPDFFormFieldObjectHelper ph(parent);
        if (ph.isRadioButton())
        {
            // This is most likely one of the individual buttons. Try
            // calling on the parent.
            QTC::TC("qpdf", "QPDFFormFieldObjectHelper set parent radio button");
            ph.setRadioButtonValue(name);
            return;
        }
    }

    QPDFObjectHandle kids = this->oh.getKey("/Kids");
    if (! (isRadioButton() && parent.isNull() && kids.isArray()))
    {
        this->oh.warnIfPossible("don't know how to set the value"
                                " of this field as a radio button");
        return;
    }
    setFieldAttribute("/V", name);
    int nkids = kids.getArrayNItems();
    for (int i = 0; i < nkids; ++i)
    {
        QPDFObjectHandle kid = kids.getArrayItem(i);
        QPDFObjectHandle AP = kid.getKey("/AP");
        QPDFObjectHandle annot;
        if (AP.isNull())
        {
            // The widget may be below. If there is more than one,
            // just find the first one.
            QPDFObjectHandle grandkids = kid.getKey("/Kids");
            if (grandkids.isArray())
            {
                int ngrandkids = grandkids.getArrayNItems();
                for (int j = 0; j < ngrandkids; ++j)
                {
                    QPDFObjectHandle grandkid = grandkids.getArrayItem(j);
                    AP = grandkid.getKey("/AP");
                    if (! AP.isNull())
                    {
                        QTC::TC("qpdf", "QPDFFormFieldObjectHelper radio button grandkid widget");
                        annot = grandkid;
                        break;
                    }
                }
            }
        }
        else
        {
            annot = kid;
        }
        if (! annot.isInitialized())
        {
            QTC::TC("qpdf", "QPDFObjectHandle broken radio button");
            this->oh.warnIfPossible(
                "unable to set the value of this radio button");
            continue;
        }
        if (AP.isDictionary() &&
            AP.getKey("/N").isDictionary() &&
            AP.getKey("/N").hasKey(name.getName()))
        {
            QTC::TC("qpdf", "QPDFFormFieldObjectHelper turn on radio button");
            annot.replaceKey("/AS", name);
        }
        else
        {
            QTC::TC("qpdf", "QPDFFormFieldObjectHelper turn off radio button");
            annot.replaceKey("/AS", QPDFObjectHandle::newName("/Off"));
        }
    }
}