private static DataForm getSentConfigurationForm(Element configureElement) {
        DataForm completedForm = null;
        FormField formField;
        Element formElement = configureElement.element(QName.get("x", "jabber:x:data"));
        if (formElement != null) {
            completedForm = new DataForm(formElement);
        }
        String accessModel = configureElement.attributeValue("access");
        if (accessModel != null) {
            if (completedForm == null) {
                // Create a form (i.e. simulate that the user sent a form with roster groups)
                completedForm = new DataForm(DataForm.Type.submit);
                // Add the hidden field indicating that this is a node config form
                formField = completedForm.addField();
                formField.setVariable("FORM_TYPE");
                formField.setType(FormField.Type.hidden);
                formField.addValue("http://jabber.org/protocol/pubsub#node_config");
            }
            if (completedForm.getField("pubsub#access_model") == null) {
                // Add the field that will specify the access model of the node
                formField = completedForm.addField();
                formField.setType(FormField.Type.list_single);
                formField.setVariable("pubsub#access_model");
                formField.addValue(accessModel);
            }
            else {
                Log.debug("PubSubEngine: Owner sent access model in data form and as attribute: " +
                        configureElement.asXML());
            }
            // Check if a list of groups was specified
            List<Element> groups = configureElement.elements("group");
            if (!groups.isEmpty()) {
                // Add the field that will contain the specified groups
                formField = completedForm.addField();
                formField.setType(FormField.Type.list_multi);
                formField.setVariable("pubsub#roster_groups_allowed");
                // Add each group as a value of the groups field
                for (Iterator<Element> it = groups.iterator(); it.hasNext();) {
                    formField.addValue(it.next().getTextTrim());
                }
            }
        }
        return completedForm;
    }
Returns the data form included in the configure element sent by the node owner or
{@code null} if none was included or access model was defined. If the
owner just wants to set the access model to use for the node and optionally set the
list of roster groups (i.e. contacts present in the node owner roster in the
specified groups are allowed to access the node) allowed to access the node then
instead of including a data form the owner can just specify the "access" attribute
of the configure element and optionally include a list of group elements. In this case,
the method will create a data form including the specified data. This is a nice way
to accept both ways to configure a node but always returning a data form.

@param configureElement the configure element sent by the owner.
@return the data form included in the configure element sent by the node owner or
        {@code null} if none was included or access model was defined.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/PubSubEngine.java