void configure(DataForm options) {
        List<String> values;

        boolean wasUsingPresence = !presenceStates.isEmpty();

        // Remove this field from the form
        options.removeField("FORM_TYPE");
        // Process and remove specific collection node fields
        FormField collectionField = options.getField("pubsub#subscription_type");
        if (collectionField != null) {
            values = collectionField.getValues();
            if (!values.isEmpty())  {
                type = Type.valueOf(values.get(0));
            }
            options.removeField("pubsub#subscription_type");
        }
        collectionField = options.getField("pubsub#subscription_depth");
        if (collectionField != null) {
            values = collectionField.getValues();
            depth = "all".equals(values.get(0)) ? 0 : 1;
            options.removeField("pubsub#subscription_depth");
        }
        // If there are more fields in the form then process them and set that
        // the subscription has been configured
        for (FormField field : options.getFields()) {
            boolean fieldExists = true;
            if ("pubsub#deliver".equals(field.getVariable())) {
                deliverNotifications = parseFirstValueAsBoolean( field, true ) ;
            }
            else if ("pubsub#digest".equals(field.getVariable())) {
                usingDigest = parseFirstValueAsBoolean( field, true ) ;
            }
            else if ("pubsub#digest_frequency".equals(field.getVariable())) {
                values = field.getValues();
                digestFrequency = !values.isEmpty() ? Integer.parseInt(values.get(0)) : 86400000;
            }
            else if ("pubsub#expire".equals(field.getVariable())) {
                values = field.getValues();
                try {
                    expire = xmppDateTime.parseString(values.get(0));
                } catch (ParseException e) {
                    Log.error("Error parsing date", e);
                }
            }
            else if ("pubsub#include_body".equals(field.getVariable())) {
                includingBody = parseFirstValueAsBoolean( field, true ) ;
            }
            else if ("pubsub#show-values".equals(field.getVariable())) {
                // Get the new list of presence states for which an entity wants to
                // receive notifications
                presenceStates = new ArrayList<>();
                for (String value : field.getValues()) {
                    try {
                        presenceStates.add(value);
                    }
                    catch (Exception e) {
                        // Do nothing
                    }
                }
            }
            else if ("x-pubsub#keywords".equals(field.getVariable())) {
                values = field.getValues();
                keyword = values.isEmpty() ? null : values.get(0);
            }
            else {
                fieldExists = false;
            }
            if (fieldExists) {
                // Subscription has been configured so set the next state
                if (node.getAccessModel().isAuthorizationRequired() && !node.isAdmin(owner)) {
                    state = State.pending;
                }
                else {
                    state = State.subscribed;
                }
            }
        }
        if (savedToDB) {
            // Update the subscription in the backend store
            XMPPServer.getInstance().getPubSubModule().getPersistenceProvider().updateSubscription(node, this);
        }
        // Check if the service needs to subscribe or unsubscribe from the owner presence
        if (!node.isPresenceBasedDelivery() && wasUsingPresence != !presenceStates.isEmpty()) {
            if (presenceStates.isEmpty()) {
                node.getService().presenceSubscriptionNotRequired(node, owner);
            }
            else {
                node.getService().presenceSubscriptionRequired(node, owner);
            }
        }
    }
Configures the subscription based on the sent {@link DataForm} included in the IQ
packet sent by the subscriber. If the subscription was pending of configuration
then the last published item is going to be sent to the subscriber.

The originalIQ parameter may be {@code null} when using this API internally. When no
IQ packet was sent then no IQ result will be sent to the sender. The rest of the
functionality is the same.

@param originalIQ the IQ packet sent by the subscriber to configure his subscription or
       null when using this API internally.
@param options the data form containing the new subscription configuration.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/NodeSubscription.java