/*
 * Copyright 2004-2019 the Pacemaker project contributors
 *
 * The version control history for this file may have further details.
 *
 * This source code is licensed under the GNU General Public License version 2
 * or later (GPLv2+) WITHOUT ANY WARRANTY.
 */

#include <crm_internal.h>

#include <sys/param.h>
#include <sys/types.h>
#include <regex.h>

#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>

#include <glib.h>

#include <crm/pengine/status.h>
#include <pengine.h>
#include <allocate.h>
#include <utils.h>
#include <crm/pengine/rules.h>

enum pe_order_kind {
    pe_order_kind_optional,
    pe_order_kind_mandatory,
    pe_order_kind_serialize,
};

#define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do {				\
	__rsc = pe_find_constraint_resource(data_set->resources, __name);		\
	if(__rsc == NULL) {						\
	    crm_config_err("%s: No resource found for %s", __set, __name); \
	    return FALSE;						\
	}								\
    } while(0)

enum pe_ordering get_flags(const char *id, enum pe_order_kind kind,
                           const char *action_first, const char *action_then, gboolean invert);
enum pe_ordering get_asymmetrical_flags(enum pe_order_kind kind);
static pe__location_t *generate_location_rule(pe_resource_t *rsc,
                                              xmlNode *rule_xml,
                                              const char *discovery,
                                              pe_working_set_t *data_set,
                                              pe_match_data_t *match_data);

gboolean
unpack_constraints(xmlNode * xml_constraints, pe_working_set_t * data_set)
{
    xmlNode *xml_obj = NULL;
    xmlNode *lifetime = NULL;

    for (xml_obj = __xml_first_child_element(xml_constraints); xml_obj != NULL;
         xml_obj = __xml_next_element(xml_obj)) {
        const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
        const char *tag = crm_element_name(xml_obj);

        if (id == NULL) {
            crm_config_err("Constraint <%s...> must have an id", tag);
            continue;
        }

        crm_trace("Processing constraint %s %s", tag, id);

        lifetime = first_named_child(xml_obj, "lifetime");
        if (lifetime) {
            crm_config_warn("Support for the lifetime tag, used by %s, is deprecated."
                            " The rules it contains should instead be direct descendents of the constraint object",
                            id);
        }

        if (test_ruleset(lifetime, NULL, data_set->now) == FALSE) {
            crm_info("Constraint %s %s is not active", tag, id);

        } else if (safe_str_eq(XML_CONS_TAG_RSC_ORDER, tag)) {
            unpack_rsc_order(xml_obj, data_set);

        } else if (safe_str_eq(XML_CONS_TAG_RSC_DEPEND, tag)) {
            unpack_rsc_colocation(xml_obj, data_set);

        } else if (safe_str_eq(XML_CONS_TAG_RSC_LOCATION, tag)) {
            unpack_location(xml_obj, data_set);

        } else if (safe_str_eq(XML_CONS_TAG_RSC_TICKET, tag)) {
            unpack_rsc_ticket(xml_obj, data_set);

        } else {
            pe_err("Unsupported constraint type: %s", tag);
        }
    }

    return TRUE;
}

static const char *
invert_action(const char *action)
{
    if (safe_str_eq(action, RSC_START)) {
        return RSC_STOP;

    } else if (safe_str_eq(action, RSC_STOP)) {
        return RSC_START;

    } else if (safe_str_eq(action, RSC_PROMOTE)) {
        return RSC_DEMOTE;

    } else if (safe_str_eq(action, RSC_DEMOTE)) {
        return RSC_PROMOTE;

    } else if (safe_str_eq(action, RSC_PROMOTED)) {
        return RSC_DEMOTED;

    } else if (safe_str_eq(action, RSC_DEMOTED)) {
        return RSC_PROMOTED;

    } else if (safe_str_eq(action, RSC_STARTED)) {
        return RSC_STOPPED;

    } else if (safe_str_eq(action, RSC_STOPPED)) {
        return RSC_STARTED;
    }
    crm_config_warn("Unknown action: %s", action);
    return NULL;
}

static enum pe_order_kind
get_ordering_type(xmlNode * xml_obj)
{
    enum pe_order_kind kind_e = pe_order_kind_mandatory;
    const char *kind = crm_element_value(xml_obj, XML_ORDER_ATTR_KIND);

    if (kind == NULL) {
        const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);

        kind_e = pe_order_kind_mandatory;

        if (score) {
            int score_i = char2score(score);

            if (score_i == 0) {
                kind_e = pe_order_kind_optional;
            }

            /* } else if(rsc_then->variant == pe_native && rsc_first->variant >= pe_clone) { */
            /*     kind_e = pe_order_kind_optional; */
        }

    } else if (safe_str_eq(kind, "Mandatory")) {
        kind_e = pe_order_kind_mandatory;

    } else if (safe_str_eq(kind, "Optional")) {
        kind_e = pe_order_kind_optional;

    } else if (safe_str_eq(kind, "Serialize")) {
        kind_e = pe_order_kind_serialize;

    } else {
        const char *id = crm_element_value(xml_obj, XML_ATTR_ID);

        crm_config_err("Constraint %s: Unknown type '%s'", id, kind);
    }
    return kind_e;
}

static resource_t *
pe_find_constraint_resource(GListPtr rsc_list, const char *id)
{
    GListPtr rIter = NULL;

    for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
        resource_t *parent = rIter->data;
        resource_t *match = parent->fns->find_rsc(parent, id, NULL,
                                                  pe_find_renamed);

        if (match != NULL) {
            if(safe_str_neq(match->id, id)) {
                /* We found an instance of a clone instead */
                match = uber_parent(match);
                crm_debug("Found %s for %s", match->id, id);
            }
            return match;
        }
    }
    crm_trace("No match for %s", id);
    return NULL;
}

static gboolean
pe_find_constraint_tag(pe_working_set_t * data_set, const char * id, tag_t ** tag)
{
    gboolean rc = FALSE;

    *tag = NULL;
    rc = g_hash_table_lookup_extended(data_set->template_rsc_sets, id,
                                       NULL, (gpointer*) tag);

    if (rc == FALSE) {
        rc = g_hash_table_lookup_extended(data_set->tags, id,
                                          NULL, (gpointer*) tag);

        if (rc == FALSE) {
            crm_config_warn("No template/tag named '%s'", id);
            return FALSE;

        } else if (*tag == NULL) {
            crm_config_warn("No resource is tagged with '%s'", id);
            return FALSE;
        }

    } else if (*tag == NULL) {
        crm_config_warn("No resource is derived from template '%s'", id);
        return FALSE;
    }

    return rc;
}

static gboolean
valid_resource_or_tag(pe_working_set_t * data_set, const char * id,
                      resource_t ** rsc, tag_t ** tag)
{
    gboolean rc = FALSE;

    if (rsc) {
        *rsc = NULL;
        *rsc = pe_find_constraint_resource(data_set->resources, id);
        if (*rsc) {
            return TRUE;
        }
    }

    if (tag) {
        *tag = NULL;
        rc = pe_find_constraint_tag(data_set, id, tag);
    }

    return rc;
}

static gboolean
order_is_symmetrical(xmlNode * xml_obj,
                     enum pe_order_kind parent_kind, const char * parent_symmetrical_s)
{
    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *kind_s = crm_element_value(xml_obj, XML_ORDER_ATTR_KIND);
    const char *score_s = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);
    const char *symmetrical_s = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL);
    enum pe_order_kind kind = parent_kind;

    if (kind_s || score_s) {
        kind = get_ordering_type(xml_obj);
    }

    if (symmetrical_s == NULL) {
        symmetrical_s = parent_symmetrical_s;
    }

    if (symmetrical_s) {
        gboolean symmetrical = crm_is_true(symmetrical_s);

        if (symmetrical && kind == pe_order_kind_serialize) {
            crm_config_warn("Cannot invert serialized order %s."
                            " Ignoring symmetrical=\"%s\"",
                            id, symmetrical_s);
            return FALSE;
        }

        return symmetrical;

    } else {
        if (kind == pe_order_kind_serialize) {
            return FALSE;

        } else {
            return TRUE;
        }
    }
}

static gboolean
unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    int order_id = 0;
    resource_t *rsc_then = NULL;
    resource_t *rsc_first = NULL;
    gboolean invert_bool = TRUE;
    int min_required_before = 0;
    enum pe_order_kind kind = pe_order_kind_mandatory;
    enum pe_ordering cons_weight = pe_order_optional;

    const char *id_first = NULL;
    const char *id_then = NULL;
    const char *action_then = NULL;
    const char *action_first = NULL;
    const char *instance_then = NULL;
    const char *instance_first = NULL;
    const char *require_all_s = NULL;

    const char *id = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    invert_bool = order_is_symmetrical(xml_obj, kind, NULL);

    id_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN);
    id_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST);

    action_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN_ACTION);
    action_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST_ACTION);

    instance_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN_INSTANCE);
    instance_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST_INSTANCE);

    if (action_first == NULL) {
        action_first = RSC_START;
    }
    if (action_then == NULL) {
        action_then = action_first;
    }

    if (id_then == NULL || id_first == NULL) {
        crm_config_err("Constraint %s needs two sides lh: %s rh: %s",
                       id, crm_str(id_then), crm_str(id_first));
        return FALSE;
    }

    rsc_then = pe_find_constraint_resource(data_set->resources, id_then);
    rsc_first = pe_find_constraint_resource(data_set->resources, id_first);

    if (rsc_then == NULL) {
        crm_config_err("Constraint %s: no resource found for name '%s'", id, id_then);
        return FALSE;

    } else if (rsc_first == NULL) {
        crm_config_err("Constraint %s: no resource found for name '%s'", id, id_first);
        return FALSE;

    } else if (instance_then && pe_rsc_is_clone(rsc_then) == FALSE) {
        crm_config_err("Invalid constraint '%s':"
                       " Resource '%s' is not a clone but instance %s was requested",
                       id, id_then, instance_then);
        return FALSE;

    } else if (instance_first && pe_rsc_is_clone(rsc_first) == FALSE) {
        crm_config_err("Invalid constraint '%s':"
                       " Resource '%s' is not a clone but instance %s was requested",
                       id, id_first, instance_first);
        return FALSE;
    }

    if (instance_then) {
        rsc_then = find_clone_instance(rsc_then, instance_then, data_set);
        if (rsc_then == NULL) {
            crm_config_warn("Invalid constraint '%s': No instance '%s' of '%s'", id, instance_then,
                            id_then);
            return FALSE;
        }
    }

    if (instance_first) {
        rsc_first = find_clone_instance(rsc_first, instance_first, data_set);
        if (rsc_first == NULL) {
            crm_config_warn("Invalid constraint '%s': No instance '%s' of '%s'", id, instance_first,
                            id_first);
            return FALSE;
        }
    }

    require_all_s = crm_element_value(xml_obj, "require-all");
    if (require_all_s
        && crm_is_true(require_all_s) == FALSE
        && pe_rsc_is_clone(rsc_first)) {

        /* require-all=false means only one instance of the clone is required */
        min_required_before = 1;
    } else if (pe_rsc_is_clone(rsc_first)) {
        const char *min_clones_s = g_hash_table_lookup(rsc_first->meta, XML_RSC_ATTR_INCARNATION_MIN);
        if (min_clones_s) {
            /* if clone min is set, we require at a minimum X number of instances
             * to be runnable before allowing dependencies to be runnable. */
            min_required_before = crm_parse_int(min_clones_s, "0");
        }
    }

    cons_weight = pe_order_optional;
    kind = get_ordering_type(xml_obj);

    if (kind == pe_order_kind_optional && rsc_then->restart_type == pe_restart_restart) {
        crm_trace("Upgrade : recovery - implies right");
        cons_weight |= pe_order_implies_then;
    }

    if (invert_bool == FALSE) {
        cons_weight |= get_asymmetrical_flags(kind);
    } else {
        cons_weight |= get_flags(id, kind, action_first, action_then, FALSE);
    }

    /* If there is a minimum number of instances that must be runnable before
     * the 'then' action is runnable, we use a pseudo action as an intermediate step
     * start min number of clones -> pseudo action is runnable -> dependency runnable. */
    if (min_required_before) {
        GListPtr rIter = NULL;
        char *task = crm_concat(CRM_OP_RELAXED_CLONE, id, ':');
        action_t *unordered_action = get_pseudo_op(task, data_set);
        free(task);

        /* require the pseudo action to have "min_required_before" number of
         * actions to be considered runnable before allowing the pseudo action
         * to be runnable. */ 
        unordered_action->required_runnable_before = min_required_before;
        update_action_flags(unordered_action, pe_action_requires_any, __FUNCTION__, __LINE__);

        for (rIter = rsc_first->children; id && rIter; rIter = rIter->next) {
            resource_t *child = rIter->data;
            /* order each clone instance before the pseudo action */
            custom_action_order(child, generate_op_key(child->id, action_first, 0), NULL,
                                NULL, NULL, unordered_action,
                                pe_order_one_or_more | pe_order_implies_then_printed, data_set);
        }

        /* order the "then" dependency to occur after the pseudo action only if
         * the pseudo action is runnable */ 
        order_id = custom_action_order(NULL, NULL, unordered_action,
                       rsc_then, generate_op_key(rsc_then->id, action_then, 0), NULL,
                       cons_weight | pe_order_runnable_left, data_set);
    } else {
        order_id = new_rsc_order(rsc_first, action_first, rsc_then, action_then, cons_weight, data_set);
    }

    pe_rsc_trace(rsc_first, "order-%d (%s): %s_%s before %s_%s flags=0x%.6x",
                 order_id, id, rsc_first->id, action_first, rsc_then->id, action_then, cons_weight);

    if (invert_bool == FALSE) {
        return TRUE;
    }

    action_then = invert_action(action_then);
    action_first = invert_action(action_first);
    if (action_then == NULL || action_first == NULL) {
        crm_config_err("Cannot invert rsc_order constraint %s."
                       " Please specify the inverse manually.", id);
        return TRUE;
    }

    cons_weight = pe_order_optional;
    if (kind == pe_order_kind_optional && rsc_then->restart_type == pe_restart_restart) {
        crm_trace("Upgrade : recovery - implies left");
        cons_weight |= pe_order_implies_first;
    }

    cons_weight |= get_flags(id, kind, action_first, action_then, TRUE);

    order_id = new_rsc_order(rsc_then, action_then, rsc_first, action_first, cons_weight, data_set);

    pe_rsc_trace(rsc_then, "order-%d (%s): %s_%s before %s_%s flags=0x%.6x",
                 order_id, id, rsc_then->id, action_then, rsc_first->id, action_first, cons_weight);

    return TRUE;
}

static gboolean
expand_tags_in_sets(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
{
    xmlNode *new_xml = NULL;
    xmlNode *set = NULL;
    gboolean any_refs = FALSE;
    const char *cons_id = NULL;

    *expanded_xml = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    new_xml = copy_xml(xml_obj);
    cons_id = ID(new_xml);

    for (set = __xml_first_child_element(new_xml); set != NULL;
         set = __xml_next_element(set)) {

        xmlNode *xml_rsc = NULL;
        GListPtr tag_refs = NULL;
        GListPtr gIter = NULL;

        if (safe_str_neq((const char *)set->name, XML_CONS_TAG_RSC_SET)) {
            continue;
        }

        for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            resource_t *rsc = NULL;
            tag_t *tag = NULL;
            const char *id = ID(xml_rsc);

            if (safe_str_neq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF)) {
                continue;
            }

            if (valid_resource_or_tag(data_set, id, &rsc, &tag) == FALSE) {
                crm_config_err("Constraint '%s': Invalid reference to '%s'", cons_id, id);
                free_xml(new_xml);
                return FALSE;

            } else if (rsc) {
                continue;

            } else if (tag) {
                /* The resource_ref under the resource_set references a template/tag */
                xmlNode *last_ref = xml_rsc;

                /* A sample:

                   Original XML:

                   <resource_set id="tag1-colocation-0" sequential="true">
                     <resource_ref id="rsc1"/>
                     <resource_ref id="tag1"/>
                     <resource_ref id="rsc4"/>
                   </resource_set>

                   Now we are appending rsc2 and rsc3 which are tagged with tag1 right after it:

                   <resource_set id="tag1-colocation-0" sequential="true">
                     <resource_ref id="rsc1"/>
                     <resource_ref id="tag1"/>
                     <resource_ref id="rsc2"/>
                     <resource_ref id="rsc3"/>
                     <resource_ref id="rsc4"/>
                   </resource_set>

                 */

                for (gIter = tag->refs; gIter != NULL; gIter = gIter->next) {
                    const char *obj_ref = (const char *) gIter->data;
                    xmlNode *new_rsc_ref = NULL;

                    new_rsc_ref = xmlNewDocRawNode(getDocPtr(set), NULL,
                                                   (const xmlChar *)XML_TAG_RESOURCE_REF, NULL);
                    crm_xml_add(new_rsc_ref, XML_ATTR_ID, obj_ref);
                    xmlAddNextSibling(last_ref, new_rsc_ref);

                    last_ref = new_rsc_ref;
                }

                any_refs = TRUE;

                /* Do not directly free '<resource_ref id="tag1"/>'.
                   That would break the further __xml_next_element(xml_rsc)) and cause "Invalid read" seen by valgrind.
                   So just record it into a hash table for freeing it later.
                 */
                tag_refs = g_list_append(tag_refs, xml_rsc);
            }
        }

        /* Now free '<resource_ref id="tag1"/>', and finally get:

           <resource_set id="tag1-colocation-0" sequential="true">
             <resource_ref id="rsc1"/>
             <resource_ref id="rsc2"/>
             <resource_ref id="rsc3"/>
             <resource_ref id="rsc4"/>
           </resource_set>

         */
        for (gIter = tag_refs; gIter != NULL; gIter = gIter->next) {
            xmlNode *tag_ref = gIter->data;

            free_xml(tag_ref);
        }
        g_list_free(tag_refs);
    }

    if (any_refs) {
        *expanded_xml = new_xml;
    } else {
        free_xml(new_xml);
    }

    return TRUE;
}

static gboolean
tag_to_set(xmlNode * xml_obj, xmlNode ** rsc_set, const char * attr,
                gboolean convert_rsc, pe_working_set_t * data_set)
{
    const char *cons_id = NULL;
    const char *id = NULL;

    resource_t *rsc = NULL;
    tag_t *tag = NULL;

    *rsc_set = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    if (attr == NULL) {
        crm_config_err("No attribute name to process.");
        return FALSE;
    }

    cons_id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (cons_id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    id = crm_element_value(xml_obj, attr);
    if (id == NULL) {
        return TRUE;
    }

    if (valid_resource_or_tag(data_set, id, &rsc, &tag) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", cons_id, id);
        return FALSE;

    } else if (tag) {
        GListPtr gIter = NULL;

        /* A template/tag is referenced by the "attr" attribute (first, then, rsc or with-rsc).
           Add the template/tag's corresponding "resource_set" which contains the resources derived
           from it or tagged with it under the constraint. */
        *rsc_set = create_xml_node(xml_obj, XML_CONS_TAG_RSC_SET);
        crm_xml_add(*rsc_set, XML_ATTR_ID, id);

        for (gIter = tag->refs; gIter != NULL; gIter = gIter->next) {
            const char *obj_ref = (const char *) gIter->data;
            xmlNode *rsc_ref = NULL;

            rsc_ref = create_xml_node(*rsc_set, XML_TAG_RESOURCE_REF);
            crm_xml_add(rsc_ref, XML_ATTR_ID, obj_ref);
        }

        /* Set sequential="false" for the resource_set */
        crm_xml_add(*rsc_set, "sequential", XML_BOOLEAN_FALSE);

    } else if (rsc && convert_rsc) {
        /* Even a regular resource is referenced by "attr", convert it into a resource_set.
           Because the other side of the constraint could be a template/tag reference. */
        xmlNode *rsc_ref = NULL;

        *rsc_set = create_xml_node(xml_obj, XML_CONS_TAG_RSC_SET);
        crm_xml_add(*rsc_set, XML_ATTR_ID, id);

        rsc_ref = create_xml_node(*rsc_set, XML_TAG_RESOURCE_REF);
        crm_xml_add(rsc_ref, XML_ATTR_ID, id);

    } else {
        return TRUE;
    }

    /* Remove the "attr" attribute referencing the template/tag */
    if (*rsc_set) {
        xml_remove_prop(xml_obj, attr);
    }

    return TRUE;
}

static gboolean unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role,
                             const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data);

static gboolean
unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);

    if(value) {
        resource_t *rsc_lh = pe_find_constraint_resource(data_set->resources, value);

        return unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
    }

    value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE_PATTERN);
    if(value) {
        regex_t *r_patt = calloc(1, sizeof(regex_t));
        bool invert = FALSE;
        GListPtr rIter = NULL;

        if(value[0] == '!') {
            value++;
            invert = TRUE;
        }

        if (regcomp(r_patt, value, REG_EXTENDED)) {
            crm_config_err("Bad regex '%s' for constraint '%s'", value, id);
            regfree(r_patt);
            free(r_patt);
            return FALSE;
        }

        for (rIter = data_set->resources; rIter; rIter = rIter->next) {
            resource_t *r = rIter->data;
            int nregs = 0;
            regmatch_t *pmatch = NULL;
            int status;

            if(r_patt->re_nsub > 0) {
                nregs = r_patt->re_nsub + 1;
            } else {
                nregs = 1;
            }
            pmatch = calloc(nregs, sizeof(regmatch_t));

            status = regexec(r_patt, r->id, nregs, pmatch, 0);

            if(invert == FALSE && status == 0) {
                pe_re_match_data_t re_match_data = {
                                                .string = r->id,
                                                .nregs = nregs,
                                                .pmatch = pmatch
                                               };
                pe_match_data_t match_data = {
                                                .re = &re_match_data,
                                                .params = r->parameters,
                                                .meta = r->meta,
                                             };
                crm_debug("'%s' matched '%s' for %s", r->id, value, id);
                unpack_rsc_location(xml_obj, r, NULL, NULL, data_set, &match_data);

            } if(invert && status != 0) {
                crm_debug("'%s' is an inverted match of '%s' for %s", r->id, value, id);
                unpack_rsc_location(xml_obj, r, NULL, NULL, data_set, NULL);

            } else {
                crm_trace("'%s' does not match '%s' for %s", r->id, value, id);
            }

            free(pmatch);
        }

        regfree(r_patt);
        free(r_patt);
    }

    return FALSE;
}

static gboolean
unpack_rsc_location(xmlNode * xml_obj, resource_t * rsc_lh, const char * role,
                    const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data)
{
    gboolean empty = TRUE;
    pe__location_t *location = NULL;
    const char *id_lh = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *node = crm_element_value(xml_obj, XML_CIB_TAG_NODE);
    const char *discovery = crm_element_value(xml_obj, XML_LOCATION_ATTR_DISCOVERY);

    if (rsc_lh == NULL) {
        /* only a warn as BSC adds the constraint then the resource */
        crm_config_warn("No resource (con=%s, rsc=%s)", id, id_lh);
        return FALSE;
    }

    if (score == NULL) {
        score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);
    }

    if (node != NULL && score != NULL) {
        int score_i = char2score(score);
        node_t *match = pe_find_node(data_set->nodes, node);

        if (!match) {
            return FALSE;
        }
        location = rsc2node_new(id, rsc_lh, score_i, discovery, match, data_set);

    } else {
        xmlNode *rule_xml = NULL;

        for (rule_xml = __xml_first_child_element(xml_obj); rule_xml != NULL;
             rule_xml = __xml_next_element(rule_xml)) {
            if (crm_str_eq((const char *)rule_xml->name, XML_TAG_RULE, TRUE)) {
                empty = FALSE;
                crm_trace("Unpacking %s/%s", id, ID(rule_xml));
                generate_location_rule(rsc_lh, rule_xml, discovery, data_set, match_data);
            }
        }

        if (empty) {
            crm_config_err("Invalid location constraint %s:"
                           " rsc_location must contain at least one rule", ID(xml_obj));
        }
    }

    if (role == NULL) {
        role = crm_element_value(xml_obj, XML_RULE_ATTR_ROLE);
    }

    if (location && role) {
        if (text2role(role) == RSC_ROLE_UNKNOWN) {
            pe_err("Invalid constraint %s: Bad role %s", id, role);
            return FALSE;

        } else {
            enum rsc_role_e r = text2role(role);
            switch(r) {
                case RSC_ROLE_UNKNOWN:
                case RSC_ROLE_STARTED:
                case RSC_ROLE_SLAVE:
                    /* Applies to all */
                    location->role_filter = RSC_ROLE_UNKNOWN;
                    break;
                default:
                    location->role_filter = r;
                    break;
            }
        }
    }

    return TRUE;
}

static gboolean
unpack_location_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
{
    const char *id = NULL;
    const char *id_lh = NULL;
    const char *state_lh = NULL;

    resource_t *rsc_lh = NULL;

    tag_t *tag_lh = NULL;

    xmlNode *new_xml = NULL;
    xmlNode *rsc_set_lh = NULL;

    *expanded_xml = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    /* Attempt to expand any template/tag references in possible resource sets. */
    expand_tags_in_sets(xml_obj, &new_xml, data_set);
    if (new_xml) {
        /* There are resource sets referencing templates. Return with the expanded XML. */
        crm_log_xml_trace(new_xml, "Expanded rsc_location...");
        *expanded_xml = new_xml;
        return TRUE;
    }

    id_lh = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
    if (id_lh == NULL) {
        return TRUE;
    }

    if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_lh);
        return FALSE;

    } else if (rsc_lh) {
        /* No template is referenced. */
        return TRUE;
    }

    state_lh = crm_element_value(xml_obj, XML_RULE_ATTR_ROLE);

    new_xml = copy_xml(xml_obj);

    /* Convert the template/tag reference in "rsc" into a resource_set under the rsc_location constraint. */
    if (tag_to_set(new_xml, &rsc_set_lh, XML_LOC_ATTR_SOURCE, FALSE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_lh) {
        if (state_lh) {
            /* A "rsc-role" is specified.
               Move it into the converted resource_set as a "role"" attribute. */
            crm_xml_add(rsc_set_lh, "role", state_lh);
            xml_remove_prop(new_xml, XML_RULE_ATTR_ROLE);
        }
        crm_log_xml_trace(new_xml, "Expanded rsc_location...");
        *expanded_xml = new_xml;

    } else {
        /* No sets */
        free_xml(new_xml);
    }

    return TRUE;
}

static gboolean
unpack_location_set(xmlNode * location, xmlNode * set, pe_working_set_t * data_set)
{
    xmlNode *xml_rsc = NULL;
    resource_t *resource = NULL;
    const char *set_id;
    const char *role;
    const char *local_score;

    if (set == NULL) {
        crm_config_err("No resource_set object to process.");
        return FALSE;
    }

    set_id = ID(set);
    if (set_id == NULL) {
        crm_config_err("resource_set must have an id");
        return FALSE;
    }

    role = crm_element_value(set, "role");
    local_score = crm_element_value(set, XML_RULE_ATTR_SCORE);

    for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
         xml_rsc = __xml_next_element(xml_rsc)) {

        if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
            EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc));
            unpack_rsc_location(location, resource, role, local_score, data_set, NULL);
        }
    }

    return TRUE;
}

gboolean
unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    xmlNode *set = NULL;
    gboolean any_sets = FALSE;

    xmlNode *orig_xml = NULL;
    xmlNode *expanded_xml = NULL;

    if (unpack_location_tags(xml_obj, &expanded_xml, data_set) == FALSE) {
        return FALSE;
    }

    if (expanded_xml) {
        orig_xml = xml_obj;
        xml_obj = expanded_xml;
    }

    for (set = __xml_first_child_element(xml_obj); set != NULL;
         set = __xml_next_element(set)) {

        if (crm_str_eq((const char *)set->name, XML_CONS_TAG_RSC_SET, TRUE)) {
            any_sets = TRUE;
            set = expand_idref(set, data_set->input);
            if (unpack_location_set(xml_obj, set, data_set) == FALSE) {
                if (expanded_xml) {
                    free_xml(expanded_xml);
                }
                return FALSE;
            }
        }
    }

    if (expanded_xml) {
        free_xml(expanded_xml);
        xml_obj = orig_xml;
    }

    if (any_sets == FALSE) {
        return unpack_simple_location(xml_obj, data_set);
    }

    return TRUE;
}

static int
get_node_score(const char *rule, const char *score, gboolean raw, node_t * node, resource_t *rsc)
{
    int score_f = 0;

    if (score == NULL) {
        pe_err("Rule %s: no score specified.  Assuming 0.", rule);

    } else if (raw) {
        score_f = char2score(score);

    } else {
        const char *attr_score = pe_node_attribute_calculated(node, score, rsc);

        if (attr_score == NULL) {
            crm_debug("Rule %s: node %s did not have a value for %s",
                      rule, node->details->uname, score);
            score_f = -INFINITY;

        } else {
            crm_debug("Rule %s: node %s had value %s for %s",
                      rule, node->details->uname, attr_score, score);
            score_f = char2score(attr_score);
        }
    }
    return score_f;
}

static pe__location_t *
generate_location_rule(pe_resource_t *rsc, xmlNode *rule_xml,
                       const char *discovery, pe_working_set_t *data_set,
                       pe_match_data_t *match_data)
{
    const char *rule_id = NULL;
    const char *score = NULL;
    const char *boolean = NULL;
    const char *role = NULL;

    GListPtr gIter = NULL;
    GListPtr match_L = NULL;

    gboolean do_and = TRUE;
    gboolean accept = TRUE;
    gboolean raw_score = TRUE;
    gboolean score_allocated = FALSE;

    pe__location_t *location_rule = NULL;

    rule_xml = expand_idref(rule_xml, data_set->input);
    rule_id = crm_element_value(rule_xml, XML_ATTR_ID);
    boolean = crm_element_value(rule_xml, XML_RULE_ATTR_BOOLEAN_OP);
    role = crm_element_value(rule_xml, XML_RULE_ATTR_ROLE);

    crm_trace("Processing rule: %s", rule_id);

    if (role != NULL && text2role(role) == RSC_ROLE_UNKNOWN) {
        pe_err("Bad role specified for %s: %s", rule_id, role);
        return NULL;
    }

    score = crm_element_value(rule_xml, XML_RULE_ATTR_SCORE);
    if (score == NULL) {
        score = crm_element_value(rule_xml, XML_RULE_ATTR_SCORE_ATTRIBUTE);
        if (score != NULL) {
            raw_score = FALSE;
        }
    }
    if (safe_str_eq(boolean, "or")) {
        do_and = FALSE;
    }

    location_rule = rsc2node_new(rule_id, rsc, 0, discovery, NULL, data_set);

    if (location_rule == NULL) {
        return NULL;
    }

    if (match_data && match_data->re && match_data->re->nregs > 0 && match_data->re->pmatch[0].rm_so != -1) {
        if (raw_score == FALSE) {
            char *result = pe_expand_re_matches(score, match_data->re);

            if (result) {
                score = (const char *) result;
                score_allocated = TRUE;
            }
        }
    }

    if (role != NULL) {
        crm_trace("Setting role filter: %s", role);
        location_rule->role_filter = text2role(role);
        if (location_rule->role_filter == RSC_ROLE_SLAVE) {
            /* Any master/slave cannot be promoted without being a slave first
             * Ergo, any constraint for the slave role applies to every role
             */
            location_rule->role_filter = RSC_ROLE_UNKNOWN;
        }
    }
    if (do_and) {
        GListPtr gIter = NULL;

        match_L = node_list_dup(data_set->nodes, TRUE, FALSE);
        for (gIter = match_L; gIter != NULL; gIter = gIter->next) {
            node_t *node = (node_t *) gIter->data;

            node->weight = get_node_score(rule_id, score, raw_score, node, rsc);
        }
    }

    for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
        int score_f = 0;
        node_t *node = (node_t *) gIter->data;

        accept = pe_test_rule_full(rule_xml, node->details->attrs, RSC_ROLE_UNKNOWN, data_set->now, match_data);

        crm_trace("Rule %s %s on %s", ID(rule_xml), accept ? "passed" : "failed",
                  node->details->uname);

        score_f = get_node_score(rule_id, score, raw_score, node, rsc);
/* 			if(accept && score_f == -INFINITY) { */
/* 				accept = FALSE; */
/* 			} */

        if (accept) {
            node_t *local = pe_find_node_id(match_L, node->details->id);

            if (local == NULL && do_and) {
                continue;

            } else if (local == NULL) {
                local = node_copy(node);
                match_L = g_list_append(match_L, local);
            }

            if (do_and == FALSE) {
                local->weight = merge_weights(local->weight, score_f);
            }
            crm_trace("node %s now has weight %d", node->details->uname, local->weight);

        } else if (do_and && !accept) {
            /* remove it */
            node_t *delete = pe_find_node_id(match_L, node->details->id);

            if (delete != NULL) {
                match_L = g_list_remove(match_L, delete);
                crm_trace("node %s did not match", node->details->uname);
            }
            free(delete);
        }
    }

    if (score_allocated == TRUE) {
        free((char *)score);
    }

    location_rule->node_list_rh = match_L;
    if (location_rule->node_list_rh == NULL) {
        crm_trace("No matching nodes for rule %s", rule_id);
        return NULL;
    }

    crm_trace("%s: %d nodes matched", rule_id, g_list_length(location_rule->node_list_rh));
    return location_rule;
}

static gint
sort_cons_priority_lh(gconstpointer a, gconstpointer b)
{
    const rsc_colocation_t *rsc_constraint1 = (const rsc_colocation_t *)a;
    const rsc_colocation_t *rsc_constraint2 = (const rsc_colocation_t *)b;

    if (a == NULL) {
        return 1;
    }
    if (b == NULL) {
        return -1;
    }

    CRM_ASSERT(rsc_constraint1->rsc_lh != NULL);
    CRM_ASSERT(rsc_constraint1->rsc_rh != NULL);

    if (rsc_constraint1->rsc_lh->priority > rsc_constraint2->rsc_lh->priority) {
        return -1;
    }

    if (rsc_constraint1->rsc_lh->priority < rsc_constraint2->rsc_lh->priority) {
        return 1;
    }

    /* Process clones before primitives and groups */
    if (rsc_constraint1->rsc_lh->variant > rsc_constraint2->rsc_lh->variant) {
        return -1;
    } else if (rsc_constraint1->rsc_lh->variant < rsc_constraint2->rsc_lh->variant) {
        return 1;
    }

    return strcmp(rsc_constraint1->rsc_lh->id, rsc_constraint2->rsc_lh->id);
}

static gint
sort_cons_priority_rh(gconstpointer a, gconstpointer b)
{
    const rsc_colocation_t *rsc_constraint1 = (const rsc_colocation_t *)a;
    const rsc_colocation_t *rsc_constraint2 = (const rsc_colocation_t *)b;

    if (a == NULL) {
        return 1;
    }
    if (b == NULL) {
        return -1;
    }

    CRM_ASSERT(rsc_constraint1->rsc_lh != NULL);
    CRM_ASSERT(rsc_constraint1->rsc_rh != NULL);

    if (rsc_constraint1->rsc_rh->priority > rsc_constraint2->rsc_rh->priority) {
        return -1;
    }

    if (rsc_constraint1->rsc_rh->priority < rsc_constraint2->rsc_rh->priority) {
        return 1;
    }

    /* Process clones before primitives and groups */
    if (rsc_constraint1->rsc_rh->variant > rsc_constraint2->rsc_rh->variant) {
        return -1;
    } else if (rsc_constraint1->rsc_rh->variant < rsc_constraint2->rsc_rh->variant) {
        return 1;
    }

    return strcmp(rsc_constraint1->rsc_rh->id, rsc_constraint2->rsc_rh->id);
}

static void
anti_colocation_order(resource_t * first_rsc, int first_role,
                      resource_t * then_rsc, int then_role,
                      pe_working_set_t * data_set)
{
    const char *first_tasks[] = { NULL, NULL };
    const char *then_tasks[] = { NULL, NULL };
    int first_lpc = 0;
    int then_lpc = 0;

    /* Actions to make first_rsc lose first_role */
    if (first_role == RSC_ROLE_MASTER) {
        first_tasks[0] = CRMD_ACTION_DEMOTE;

    } else {
        first_tasks[0] = CRMD_ACTION_STOP;

        if (first_role == RSC_ROLE_SLAVE) {
            first_tasks[1] = CRMD_ACTION_PROMOTE;
        }
    }

    /* Actions to make then_rsc gain then_role */
    if (then_role == RSC_ROLE_MASTER) {
        then_tasks[0] = CRMD_ACTION_PROMOTE;

    } else {
        then_tasks[0] = CRMD_ACTION_START;

        if (then_role == RSC_ROLE_SLAVE) {
            then_tasks[1] = CRMD_ACTION_DEMOTE;
        }
    }

    for (first_lpc = 0; first_lpc <= 1 && first_tasks[first_lpc] != NULL; first_lpc++) {
        for (then_lpc = 0; then_lpc <= 1 && then_tasks[then_lpc] != NULL; then_lpc++) {
            new_rsc_order(first_rsc, first_tasks[first_lpc], then_rsc, then_tasks[then_lpc],
                          pe_order_anti_colocation, data_set);
        }
    }
}

gboolean
rsc_colocation_new(const char *id, const char *node_attr, int score,
                   resource_t * rsc_lh, resource_t * rsc_rh,
                   const char *state_lh, const char *state_rh, pe_working_set_t * data_set)
{
    rsc_colocation_t *new_con = NULL;

    if (rsc_lh == NULL) {
        crm_config_err("No resource found for LHS %s", id);
        return FALSE;

    } else if (rsc_rh == NULL) {
        crm_config_err("No resource found for RHS of %s", id);
        return FALSE;
    }

    new_con = calloc(1, sizeof(rsc_colocation_t));
    if (new_con == NULL) {
        return FALSE;
    }

    if (state_lh == NULL || safe_str_eq(state_lh, RSC_ROLE_STARTED_S)) {
        state_lh = RSC_ROLE_UNKNOWN_S;
    }

    if (state_rh == NULL || safe_str_eq(state_rh, RSC_ROLE_STARTED_S)) {
        state_rh = RSC_ROLE_UNKNOWN_S;
    }

    new_con->id = id;
    new_con->rsc_lh = rsc_lh;
    new_con->rsc_rh = rsc_rh;
    new_con->score = score;
    new_con->role_lh = text2role(state_lh);
    new_con->role_rh = text2role(state_rh);
    new_con->node_attribute = node_attr;

    if (node_attr == NULL) {
        node_attr = CRM_ATTR_UNAME;
    }

    pe_rsc_trace(rsc_lh, "%s ==> %s (%s %d)", rsc_lh->id, rsc_rh->id, node_attr, score);

    rsc_lh->rsc_cons = g_list_insert_sorted(rsc_lh->rsc_cons, new_con, sort_cons_priority_rh);

    rsc_rh->rsc_cons_lhs =
        g_list_insert_sorted(rsc_rh->rsc_cons_lhs, new_con, sort_cons_priority_lh);

    data_set->colocation_constraints = g_list_append(data_set->colocation_constraints, new_con);

    if (score <= -INFINITY) {
        anti_colocation_order(rsc_lh, new_con->role_lh, rsc_rh, new_con->role_rh, data_set);
        anti_colocation_order(rsc_rh, new_con->role_rh, rsc_lh, new_con->role_lh, data_set);
    }

    return TRUE;
}

/* LHS before RHS */
int
new_rsc_order(resource_t * lh_rsc, const char *lh_task,
              resource_t * rh_rsc, const char *rh_task,
              enum pe_ordering type, pe_working_set_t * data_set)
{
    char *lh_key = NULL;
    char *rh_key = NULL;

    CRM_CHECK(lh_rsc != NULL, return -1);
    CRM_CHECK(lh_task != NULL, return -1);
    CRM_CHECK(rh_rsc != NULL, return -1);
    CRM_CHECK(rh_task != NULL, return -1);

    /* We no longer need to test if these reference stonith resources
     * now that stonithd has access to them even when they're not "running"
     *
    if (validate_order_resources(lh_rsc, lh_task, rh_rsc, rh_task)) {
        return -1;
    }
    */

    lh_key = generate_op_key(lh_rsc->id, lh_task, 0);
    rh_key = generate_op_key(rh_rsc->id, rh_task, 0);

    return custom_action_order(lh_rsc, lh_key, NULL, rh_rsc, rh_key, NULL, type, data_set);
}

static char *
task_from_action_or_key(action_t *action, const char *key)
{
    char *res = NULL;

    if (action) {
        res = strdup(action->task);
    } else if (key) {
        parse_op_key(key, NULL, &res, NULL);
    }
    return res;
}

/* when order constraints are made between two resources start and stop actions
 * those constraints have to be mirrored against the corresponding
 * migration actions to ensure start/stop ordering is preserved during
 * a migration */
static void
handle_migration_ordering(pe__ordering_t *order, pe_working_set_t *data_set)
{
    char *lh_task = NULL;
    char *rh_task = NULL;
    gboolean rh_migratable;
    gboolean lh_migratable;

    if (order->lh_rsc == NULL || order->rh_rsc == NULL) {
        return;
    } else if (order->lh_rsc == order->rh_rsc) {
        return;
    /* don't mess with those constraints built between parent
     * resources and the children */
    } else if (is_parent(order->lh_rsc, order->rh_rsc)) {
        return;
    } else if (is_parent(order->rh_rsc, order->lh_rsc)) {
        return;
    }

    lh_migratable = is_set(order->lh_rsc->flags, pe_rsc_allow_migrate);
    rh_migratable = is_set(order->rh_rsc->flags, pe_rsc_allow_migrate);

    /* one of them has to be migratable for
     * the migrate ordering logic to be applied */
    if (lh_migratable == FALSE && rh_migratable == FALSE) {
        return;
    }

    /* at this point we have two resources which allow migrations that have an
     * order dependency set between them.  If those order dependencies involve
     * start/stop actions, we need to mirror the corresponding migrate actions
     * so order will be preserved. */
    lh_task = task_from_action_or_key(order->lh_action, order->lh_action_task);
    rh_task = task_from_action_or_key(order->rh_action, order->rh_action_task);
    if (lh_task == NULL || rh_task == NULL) {
        goto cleanup_order;
    }

    if (safe_str_eq(lh_task, RSC_START) && safe_str_eq(rh_task, RSC_START)) {
        int flags = pe_order_optional;

        if (lh_migratable && rh_migratable) {
            /* A start then B start
             * A migrate_from then B migrate_to */
            custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_MIGRATED, 0), NULL,
                                order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATE, 0), NULL,
                                flags, data_set);
        }

        if (rh_migratable) {
            if (lh_migratable) {
                flags |= pe_order_apply_first_non_migratable;
            }

            /* A start then B start
             * A start then B migrate_to... only if A start is not a part of a migration*/
            custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_START, 0), NULL,
                                order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATE, 0), NULL,
                                flags, data_set);
        }

    } else if (rh_migratable == TRUE && safe_str_eq(lh_task, RSC_STOP) && safe_str_eq(rh_task, RSC_STOP)) {
        int flags = pe_order_optional;

        if (lh_migratable) {
            flags |= pe_order_apply_first_non_migratable;
        }

        /* rh side is at the bottom of the stack during a stop. If we have a constraint
         * stop B then stop A, if B is migrating via stop/start, and A is migrating using migration actions,
         * we need to enforce that A's migrate_to action occurs after B's stop action. */
        custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_STOP, 0), NULL,
                            order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATE, 0), NULL,
                            flags, data_set);

        /* We need to build the stop constraint against migrate_from as well
         * to account for partial migrations. */
        if (order->rh_rsc->partial_migration_target) {
            custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_STOP, 0), NULL,
                                order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATED, 0), NULL,
                                flags, data_set);
        }

    } else if (safe_str_eq(lh_task, RSC_PROMOTE) && safe_str_eq(rh_task, RSC_START)) {
        int flags = pe_order_optional;

        if (rh_migratable) {
            /* A promote then B start
             * A promote then B migrate_to */
            custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_PROMOTE, 0), NULL,
                                order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATE, 0), NULL,
                                flags, data_set);
        }

    } else if (safe_str_eq(lh_task, RSC_DEMOTE) && safe_str_eq(rh_task, RSC_STOP)) {
        int flags = pe_order_optional;

        if (rh_migratable) {
            /* A demote then B stop
             * A demote then B migrate_to */
            custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_DEMOTE, 0), NULL,
                                order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATE, 0), NULL,
                                flags, data_set);

            /* We need to build the demote constraint against migrate_from as well
             * to account for partial migrations. */
            if (order->rh_rsc->partial_migration_target) {
                custom_action_order(order->lh_rsc, generate_op_key(order->lh_rsc->id, RSC_DEMOTE, 0), NULL,
                                    order->rh_rsc, generate_op_key(order->rh_rsc->id, RSC_MIGRATED, 0), NULL,
                                    flags, data_set);
            }
        }
    }

cleanup_order:
    free(lh_task);
    free(rh_task);
}

/* LHS before RHS */
int
custom_action_order(resource_t * lh_rsc, char *lh_action_task, action_t * lh_action,
                    resource_t * rh_rsc, char *rh_action_task, action_t * rh_action,
                    enum pe_ordering type, pe_working_set_t * data_set)
{
    pe__ordering_t *order = NULL;

    if (lh_rsc == NULL && lh_action) {
        lh_rsc = lh_action->rsc;
    }
    if (rh_rsc == NULL && rh_action) {
        rh_rsc = rh_action->rsc;
    }

    if ((lh_action == NULL && lh_rsc == NULL)
        || (rh_action == NULL && rh_rsc == NULL)) {
        crm_config_err("Invalid inputs %p.%p %p.%p", lh_rsc, lh_action, rh_rsc, rh_action);
        free(lh_action_task);
        free(rh_action_task);
        return -1;
    }

    order = calloc(1, sizeof(pe__ordering_t));

    crm_trace("Creating[%d] %s %s %s - %s %s %s", data_set->order_id,
              lh_rsc?lh_rsc->id:"NA", lh_action_task, lh_action?lh_action->uuid:"NA",
              rh_rsc?rh_rsc->id:"NA", rh_action_task, rh_action?rh_action->uuid:"NA");

    /* CRM_ASSERT(data_set->order_id != 291); */

    order->id = data_set->order_id++;
    order->type = type;
    order->lh_rsc = lh_rsc;
    order->rh_rsc = rh_rsc;
    order->lh_action = lh_action;
    order->rh_action = rh_action;
    order->lh_action_task = lh_action_task;
    order->rh_action_task = rh_action_task;

    if (order->lh_action_task == NULL && lh_action) {
        order->lh_action_task = strdup(lh_action->uuid);
    }

    if (order->rh_action_task == NULL && rh_action) {
        order->rh_action_task = strdup(rh_action->uuid);
    }

    if (order->lh_rsc == NULL && lh_action) {
        order->lh_rsc = lh_action->rsc;
    }

    if (order->rh_rsc == NULL && rh_action) {
        order->rh_rsc = rh_action->rsc;
    }

    data_set->ordering_constraints = g_list_prepend(data_set->ordering_constraints, order);
    handle_migration_ordering(order, data_set);

    return order->id;
}

enum pe_ordering
get_asymmetrical_flags(enum pe_order_kind kind)
{
    enum pe_ordering flags = pe_order_optional;

    if (kind == pe_order_kind_mandatory) {
        flags |= pe_order_asymmetrical;
    } else if (kind == pe_order_kind_serialize) {
        flags |= pe_order_serialize_only;
    }
    return flags;
}

enum pe_ordering
get_flags(const char *id, enum pe_order_kind kind,
          const char *action_first, const char *action_then, gboolean invert)
{
    enum pe_ordering flags = pe_order_optional;

    if (invert && kind == pe_order_kind_mandatory) {
        crm_trace("Upgrade %s: implies left", id);
        flags |= pe_order_implies_first;

    } else if (kind == pe_order_kind_mandatory) {
        crm_trace("Upgrade %s: implies right", id);
        flags |= pe_order_implies_then;
        if (safe_str_eq(action_first, RSC_START)
            || safe_str_eq(action_first, RSC_PROMOTE)) {
            crm_trace("Upgrade %s: runnable", id);
            flags |= pe_order_runnable_left;
        }

    } else if (kind == pe_order_kind_serialize) {
        flags |= pe_order_serialize_only;
    }

    return flags;
}

static gboolean
unpack_order_set(xmlNode * set, enum pe_order_kind parent_kind, resource_t ** rsc,
                 action_t ** begin, action_t ** end, action_t ** inv_begin, action_t ** inv_end,
                 const char *parent_symmetrical_s, pe_working_set_t * data_set)
{
    xmlNode *xml_rsc = NULL;
    GListPtr set_iter = NULL;
    GListPtr resources = NULL;

    resource_t *last = NULL;
    resource_t *resource = NULL;

    int local_kind = parent_kind;
    gboolean sequential = FALSE;
    enum pe_ordering flags = pe_order_optional;
    gboolean symmetrical = TRUE;

    char *key = NULL;
    const char *id = ID(set);
    const char *action = crm_element_value(set, "action");
    const char *sequential_s = crm_element_value(set, "sequential");
    const char *kind_s = crm_element_value(set, XML_ORDER_ATTR_KIND);

    /*
       char *pseudo_id = NULL;
       char *end_id    = NULL;
       char *begin_id  = NULL;
     */

    if (action == NULL) {
        action = RSC_START;
    }

    if (kind_s) {
        local_kind = get_ordering_type(set);
    }
    if (sequential_s == NULL) {
        sequential_s = "1";
    }

    sequential = crm_is_true(sequential_s);

    symmetrical = order_is_symmetrical(set, parent_kind, parent_symmetrical_s);
    if (symmetrical) {
        flags = get_flags(id, local_kind, action, action, FALSE);
    } else {
        flags = get_asymmetrical_flags(local_kind);
    }

    for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
         xml_rsc = __xml_next_element(xml_rsc)) {

        if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
            EXPAND_CONSTRAINT_IDREF(id, resource, ID(xml_rsc));
            resources = g_list_append(resources, resource);
        }
    }

    if (g_list_length(resources) == 1) {
        crm_trace("Single set: %s", id);
        *rsc = resource;
        *end = NULL;
        *begin = NULL;
        *inv_end = NULL;
        *inv_begin = NULL;
        goto done;
    }

    /*
       pseudo_id = crm_concat(id, action, '-');
       end_id    = crm_concat(pseudo_id, "end", '-');
       begin_id  = crm_concat(pseudo_id, "begin", '-');
     */

    *rsc = NULL;
    /*
     *end = get_pseudo_op(end_id, data_set);
     *begin = get_pseudo_op(begin_id, data_set);

     free(pseudo_id);
     free(begin_id);
     free(end_id);
     */

    set_iter = resources;
    while (set_iter != NULL) {
        resource = (resource_t *) set_iter->data;
        set_iter = set_iter->next;

        key = generate_op_key(resource->id, action, 0);

        /*
           custom_action_order(NULL, NULL, *begin, resource, strdup(key), NULL,
           flags|pe_order_implies_first_printed, data_set);

           custom_action_order(resource, strdup(key), NULL, NULL, NULL, *end,
           flags|pe_order_implies_then_printed, data_set);
         */

        if (local_kind == pe_order_kind_serialize) {
            /* Serialize before everything that comes after */

            GListPtr gIter = NULL;

            for (gIter = set_iter; gIter != NULL; gIter = gIter->next) {
                resource_t *then_rsc = (resource_t *) gIter->data;
                char *then_key = generate_op_key(then_rsc->id, action, 0);

                custom_action_order(resource, strdup(key), NULL, then_rsc, then_key, NULL,
                                    flags, data_set);
            }

        } else if (sequential) {
            if (last != NULL) {
                new_rsc_order(last, action, resource, action, flags, data_set);
            }
            last = resource;
        }
        free(key);
    }

    if (symmetrical == FALSE) {
        goto done;
    }

    last = NULL;
    action = invert_action(action);

    /*
       pseudo_id = crm_concat(id, action, '-');
       end_id    = crm_concat(pseudo_id, "end", '-');
       begin_id  = crm_concat(pseudo_id, "begin", '-');

       *inv_end = get_pseudo_op(end_id, data_set);
       *inv_begin = get_pseudo_op(begin_id, data_set);

       free(pseudo_id);
       free(begin_id);
       free(end_id);
     */

    flags = get_flags(id, local_kind, action, action, TRUE);

    set_iter = resources;
    while (set_iter != NULL) {
        resource = (resource_t *) set_iter->data;
        set_iter = set_iter->next;

        /*
           key = generate_op_key(resource->id, action, 0);

           custom_action_order(NULL, NULL, *inv_begin, resource, strdup(key), NULL,
           flags|pe_order_implies_first_printed, data_set);

           custom_action_order(resource, key, NULL, NULL, NULL, *inv_end,
           flags|pe_order_implies_then_printed, data_set);
         */

        if (sequential) {
            if (last != NULL) {
                new_rsc_order(resource, action, last, action, flags, data_set);
            }
            last = resource;
        }
    }

  done:
    g_list_free(resources);
    return TRUE;
}

static gboolean
order_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, enum pe_order_kind kind,
               pe_working_set_t * data_set, gboolean invert, gboolean symmetrical)
{

    xmlNode *xml_rsc = NULL;
    xmlNode *xml_rsc_2 = NULL;

    resource_t *rsc_1 = NULL;
    resource_t *rsc_2 = NULL;

    const char *action_1 = crm_element_value(set1, "action");
    const char *action_2 = crm_element_value(set2, "action");

    const char *sequential_1 = crm_element_value(set1, "sequential");
    const char *sequential_2 = crm_element_value(set2, "sequential");

    const char *require_all_s = crm_element_value(set1, "require-all");
    gboolean require_all = require_all_s ? crm_is_true(require_all_s) : TRUE;

    enum pe_ordering flags = pe_order_none;

    if (action_1 == NULL) {
        action_1 = RSC_START;
    };

    if (action_2 == NULL) {
        action_2 = RSC_START;
    };

    if (invert) {
        action_1 = invert_action(action_1);
        action_2 = invert_action(action_2);
    }

    if(safe_str_eq(RSC_STOP, action_1) || safe_str_eq(RSC_DEMOTE, action_1)) {
        /* Assuming: A -> ( B || C) -> D
         * The one-or-more logic only applies during the start/promote phase
         * During shutdown neither B nor can shutdown until D is down, so simply turn require_all back on.
         */
        require_all = TRUE;
    }

    if (symmetrical == FALSE) {
        flags = get_asymmetrical_flags(kind);
    } else {
        flags = get_flags(id, kind, action_2, action_1, invert);
    }

    /* If we have an un-ordered set1, whether it is sequential or not is irrelevant in regards to set2. */
    if (!require_all) {
        char *task = crm_concat(CRM_OP_RELAXED_SET, ID(set1), ':');
        action_t *unordered_action = get_pseudo_op(task, data_set);

        free(task);
        update_action_flags(unordered_action, pe_action_requires_any, __FUNCTION__, __LINE__);

        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (!crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                continue;
            }

            EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));

            /* Add an ordering constraint between every element in set1 and the pseudo action.
             * If any action in set1 is runnable the pseudo action will be runnable. */
            custom_action_order(rsc_1, generate_op_key(rsc_1->id, action_1, 0), NULL,
                                NULL, NULL, unordered_action,
                                pe_order_one_or_more | pe_order_implies_then_printed, data_set);
        }
        for (xml_rsc_2 = __xml_first_child_element(set2); xml_rsc_2 != NULL;
             xml_rsc_2 = __xml_next_element(xml_rsc_2)) {

            if (!crm_str_eq((const char *)xml_rsc_2->name, XML_TAG_RESOURCE_REF, TRUE)) {
                continue;
            }

            EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc_2));

            /* Add an ordering constraint between the pseudo action and every element in set2.
             * If the pseudo action is runnable, every action in set2 will be runnable */
            custom_action_order(NULL, NULL, unordered_action,
                                rsc_2, generate_op_key(rsc_2->id, action_2, 0), NULL,
                                flags | pe_order_runnable_left, data_set);
        }

        return TRUE;
    }

    if (crm_is_true(sequential_1)) {
        if (invert == FALSE) {
            /* get the last one */
            const char *rid = NULL;

            for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
                 xml_rsc = __xml_next_element(xml_rsc)) {

                if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                    rid = ID(xml_rsc);
                }
            }
            EXPAND_CONSTRAINT_IDREF(id, rsc_1, rid);

        } else {
            /* get the first one */
            for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
                 xml_rsc = __xml_next_element(xml_rsc)) {

                if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                    EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));
                    break;
                }
            }
        }
    }

    if (crm_is_true(sequential_2)) {
        if (invert == FALSE) {
            /* get the first one */
            for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
                 xml_rsc = __xml_next_element(xml_rsc)) {

                if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                    EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc));
                    break;
                }
            }

        } else {
            /* get the last one */
            const char *rid = NULL;

            for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
                 xml_rsc = __xml_next_element(xml_rsc)) {

                if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                    rid = ID(xml_rsc);
                }
            }
            EXPAND_CONSTRAINT_IDREF(id, rsc_2, rid);
        }
    }

    if (rsc_1 != NULL && rsc_2 != NULL) {
        new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set);

    } else if (rsc_1 != NULL) {
        for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc));
                new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set);
            }
        }

    } else if (rsc_2 != NULL) {
        xmlNode *xml_rsc = NULL;

        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));
                new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set);
            }
        }

    } else {
        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                xmlNode *xml_rsc_2 = NULL;

                EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));

                for (xml_rsc_2 = __xml_first_child_element(set2);
                     xml_rsc_2 != NULL;
                     xml_rsc_2 = __xml_next_element(xml_rsc_2)) {

                    if (crm_str_eq((const char *)xml_rsc_2->name, XML_TAG_RESOURCE_REF, TRUE)) {
                        EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc_2));
                        new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set);
                    }
                }
            }
        }
    }

    return TRUE;
}

static gboolean
unpack_order_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
{
    const char *id = NULL;
    const char *id_first = NULL;
    const char *id_then = NULL;
    const char *action_first = NULL;
    const char *action_then = NULL;

    resource_t *rsc_first = NULL;
    resource_t *rsc_then = NULL;
    tag_t *tag_first = NULL;
    tag_t *tag_then = NULL;

    xmlNode *new_xml = NULL;
    xmlNode *rsc_set_first = NULL;
    xmlNode *rsc_set_then = NULL;
    gboolean any_sets = FALSE;

    *expanded_xml = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    /* Attempt to expand any template/tag references in possible resource sets. */
    expand_tags_in_sets(xml_obj, &new_xml, data_set);
    if (new_xml) {
        /* There are resource sets referencing templates/tags. Return with the expanded XML. */
        crm_log_xml_trace(new_xml, "Expanded rsc_order...");
        *expanded_xml = new_xml;
        return TRUE;
    }

    id_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST);
    id_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN);
    if (id_first == NULL || id_then == NULL) {
        return TRUE;
    }

    if (valid_resource_or_tag(data_set, id_first, &rsc_first, &tag_first) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_first);
        return FALSE;
    }

    if (valid_resource_or_tag(data_set, id_then, &rsc_then, &tag_then) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_then);
        return FALSE;
    }

    if (rsc_first && rsc_then) {
        /* Neither side references any template/tag. */
        return TRUE;
    }

    action_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST_ACTION);
    action_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN_ACTION);

    new_xml = copy_xml(xml_obj);

    /* Convert the template/tag reference in "first" into a resource_set under the order constraint. */
    if (tag_to_set(new_xml, &rsc_set_first, XML_ORDER_ATTR_FIRST, TRUE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_first) {
        if (action_first) {
            /* A "first-action" is specified.
               Move it into the converted resource_set as an "action" attribute. */
            crm_xml_add(rsc_set_first, "action", action_first);
            xml_remove_prop(new_xml, XML_ORDER_ATTR_FIRST_ACTION);
        }
        any_sets = TRUE;
    }

    /* Convert the template/tag reference in "then" into a resource_set under the order constraint. */
    if (tag_to_set(new_xml, &rsc_set_then, XML_ORDER_ATTR_THEN, TRUE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_then) {
        if (action_then) {
            /* A "then-action" is specified.
               Move it into the converted resource_set as an "action" attribute. */
            crm_xml_add(rsc_set_then, "action", action_then);
            xml_remove_prop(new_xml, XML_ORDER_ATTR_THEN_ACTION);
        }
        any_sets = TRUE;
    }

    if (any_sets) {
        crm_log_xml_trace(new_xml, "Expanded rsc_order...");
        *expanded_xml = new_xml;
    } else {
        free_xml(new_xml);
    }

    return TRUE;
}

gboolean
unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    gboolean any_sets = FALSE;

    resource_t *rsc = NULL;

    /*
       resource_t *last_rsc = NULL;
     */

    action_t *set_end = NULL;
    action_t *set_begin = NULL;

    action_t *set_inv_end = NULL;
    action_t *set_inv_begin = NULL;

    xmlNode *set = NULL;
    xmlNode *last = NULL;

    xmlNode *orig_xml = NULL;
    xmlNode *expanded_xml = NULL;

    /*
       action_t *last_end = NULL;
       action_t *last_begin = NULL;
       action_t *last_inv_end = NULL;
       action_t *last_inv_begin = NULL;
     */

    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *invert = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL);
    enum pe_order_kind kind = get_ordering_type(xml_obj);

    gboolean invert_bool = order_is_symmetrical(xml_obj, kind, NULL);
    gboolean rc = TRUE;

    rc = unpack_order_tags(xml_obj, &expanded_xml, data_set);
    if (expanded_xml) {
        orig_xml = xml_obj;
        xml_obj = expanded_xml;

    } else if (rc == FALSE) {
        return FALSE;
    }

    for (set = __xml_first_child_element(xml_obj); set != NULL;
         set = __xml_next_element(set)) {

        if (crm_str_eq((const char *)set->name, XML_CONS_TAG_RSC_SET, TRUE)) {
            any_sets = TRUE;
            set = expand_idref(set, data_set->input);
            if (unpack_order_set(set, kind, &rsc, &set_begin, &set_end,
                                 &set_inv_begin, &set_inv_end, invert, data_set) == FALSE) {
                return FALSE;

                /* Expand orders in order_rsc_sets() instead of via pseudo actions. */
                /*
                   } else if(last) {
                   const char *set_action = crm_element_value(set, "action");
                   const char *last_action = crm_element_value(last, "action");
                   enum pe_ordering flags = get_flags(id, kind, last_action, set_action, FALSE);

                   if(!set_action) { set_action = RSC_START; }
                   if(!last_action) { last_action = RSC_START; }

                   if(rsc == NULL && last_rsc == NULL) {
                   order_actions(last_end, set_begin, flags);
                   } else {
                   custom_action_order(
                   last_rsc, null_or_opkey(last_rsc, last_action), last_end,
                   rsc, null_or_opkey(rsc, set_action), set_begin,
                   flags, data_set);
                   }

                   if(crm_is_true(invert)) {
                   set_action = invert_action(set_action);
                   last_action = invert_action(last_action);

                   flags = get_flags(id, kind, last_action, set_action, TRUE);
                   if(rsc == NULL && last_rsc == NULL) {
                   order_actions(last_inv_begin, set_inv_end, flags);

                   } else {
                   custom_action_order(
                   last_rsc, null_or_opkey(last_rsc, last_action), last_inv_begin,
                   rsc, null_or_opkey(rsc, set_action), set_inv_end,
                   flags, data_set);
                   }
                   }
                 */

            } else if (         /* never called -- Now call it for supporting clones in resource sets */
                          last) {
                if (order_rsc_sets(id, last, set, kind, data_set, FALSE, invert_bool) == FALSE) {
                    return FALSE;
                }

                if (invert_bool
                    && order_rsc_sets(id, set, last, kind, data_set, TRUE, invert_bool) == FALSE) {
                    return FALSE;
                }

            }
            last = set;
            /*
               last_rsc = rsc;
               last_end = set_end;
               last_begin = set_begin;
               last_inv_end = set_inv_end;
               last_inv_begin = set_inv_begin;
             */
        }
    }

    if (expanded_xml) {
        free_xml(expanded_xml);
        xml_obj = orig_xml;
    }

    if (any_sets == FALSE) {
        return unpack_simple_rsc_order(xml_obj, data_set);
    }

    return TRUE;
}

static gboolean
unpack_colocation_set(xmlNode * set, int score, pe_working_set_t * data_set)
{
    xmlNode *xml_rsc = NULL;
    resource_t *with = NULL;
    resource_t *resource = NULL;
    const char *set_id = ID(set);
    const char *role = crm_element_value(set, "role");
    const char *sequential = crm_element_value(set, "sequential");
    const char *ordering = crm_element_value(set, "ordering");
    int local_score = score;

    const char *score_s = crm_element_value(set, XML_RULE_ATTR_SCORE);

    if (score_s) {
        local_score = char2score(score_s);
    }

    if(ordering == NULL) {
        ordering = "group";
    }

    if (sequential != NULL && crm_is_true(sequential) == FALSE) {
        return TRUE;

    } else if (local_score >= 0 && safe_str_eq(ordering, "group")) {
        for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc));
                if (with != NULL) {
                    pe_rsc_trace(resource, "Colocating %s with %s", resource->id, with->id);
                    rsc_colocation_new(set_id, NULL, local_score, resource, with, role, role,
                                       data_set);
                }

                with = resource;
            }
        }
    } else if (local_score >= 0) {
        resource_t *last = NULL;
        for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc));
                if (last != NULL) {
                    pe_rsc_trace(resource, "Colocating %s with %s", last->id, resource->id);
                    rsc_colocation_new(set_id, NULL, local_score, last, resource, role, role,
                                       data_set);
                }

                last = resource;
            }
        }

    } else {
        /* Anti-colocating with every prior resource is
         * the only way to ensure the intuitive result
         * (i.e. that no one in the set can run with anyone else in the set)
         */

        for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                xmlNode *xml_rsc_with = NULL;

                EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc));

                for (xml_rsc_with = __xml_first_child_element(set);
                     xml_rsc_with != NULL;
                     xml_rsc_with = __xml_next_element(xml_rsc_with)) {

                    if (crm_str_eq((const char *)xml_rsc_with->name, XML_TAG_RESOURCE_REF, TRUE)) {
                        if (safe_str_eq(resource->id, ID(xml_rsc_with))) {
                            break;
                        }
                        EXPAND_CONSTRAINT_IDREF(set_id, with, ID(xml_rsc_with));
                        pe_rsc_trace(resource, "Anti-Colocating %s with %s", resource->id,
                                     with->id);
                        rsc_colocation_new(set_id, NULL, local_score, resource, with, role, role,
                                           data_set);
                    }
                }
            }
        }
    }

    return TRUE;
}

static gboolean
colocate_rsc_sets(const char *id, xmlNode * set1, xmlNode * set2, int score,
                  pe_working_set_t * data_set)
{
    xmlNode *xml_rsc = NULL;
    resource_t *rsc_1 = NULL;
    resource_t *rsc_2 = NULL;

    const char *role_1 = crm_element_value(set1, "role");
    const char *role_2 = crm_element_value(set2, "role");

    const char *sequential_1 = crm_element_value(set1, "sequential");
    const char *sequential_2 = crm_element_value(set2, "sequential");

    if (sequential_1 == NULL || crm_is_true(sequential_1)) {
        /* get the first one */
        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));
                break;
            }
        }
    }

    if (sequential_2 == NULL || crm_is_true(sequential_2)) {
        /* get the last one */
        const char *rid = NULL;

        for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                rid = ID(xml_rsc);
            }
        }
        EXPAND_CONSTRAINT_IDREF(id, rsc_2, rid);
    }

    if (rsc_1 != NULL && rsc_2 != NULL) {
        rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set);

    } else if (rsc_1 != NULL) {
        for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc));
                rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set);
            }
        }

    } else if (rsc_2 != NULL) {
        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));
                rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set);
            }
        }

    } else {
        for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
             xml_rsc = __xml_next_element(xml_rsc)) {

            if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) {
                xmlNode *xml_rsc_2 = NULL;

                EXPAND_CONSTRAINT_IDREF(id, rsc_1, ID(xml_rsc));

                for (xml_rsc_2 = __xml_first_child_element(set2);
                     xml_rsc_2 != NULL;
                     xml_rsc_2 = __xml_next_element(xml_rsc_2)) {

                    if (crm_str_eq((const char *)xml_rsc_2->name, XML_TAG_RESOURCE_REF, TRUE)) {
                        EXPAND_CONSTRAINT_IDREF(id, rsc_2, ID(xml_rsc_2));
                        rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set);
                    }
                }
            }
        }
    }

    return TRUE;
}

static gboolean
unpack_simple_colocation(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    int score_i = 0;

    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);

    const char *id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE);
    const char *id_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET);
    const char *state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE);
    const char *state_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE);
    const char *instance_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_INSTANCE);
    const char *instance_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_INSTANCE);
    const char *attr = crm_element_value(xml_obj, XML_COLOC_ATTR_NODE_ATTR);

    const char *symmetrical = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL);

    resource_t *rsc_lh = pe_find_constraint_resource(data_set->resources, id_lh);
    resource_t *rsc_rh = pe_find_constraint_resource(data_set->resources, id_rh);

    if (rsc_lh == NULL) {
        crm_config_err("Invalid constraint '%s': No resource named '%s'", id, id_lh);
        return FALSE;

    } else if (rsc_rh == NULL) {
        crm_config_err("Invalid constraint '%s': No resource named '%s'", id, id_rh);
        return FALSE;

    } else if (instance_lh && pe_rsc_is_clone(rsc_lh) == FALSE) {
        crm_config_err
            ("Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
             id, id_lh, instance_lh);
        return FALSE;

    } else if (instance_rh && pe_rsc_is_clone(rsc_rh) == FALSE) {
        crm_config_err
            ("Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
             id, id_rh, instance_rh);
        return FALSE;
    }

    if (instance_lh) {
        rsc_lh = find_clone_instance(rsc_lh, instance_lh, data_set);
        if (rsc_lh == NULL) {
            crm_config_warn("Invalid constraint '%s': No instance '%s' of '%s'", id, instance_lh,
                            id_lh);
            return FALSE;
        }
    }

    if (instance_rh) {
        rsc_rh = find_clone_instance(rsc_rh, instance_rh, data_set);
        if (rsc_rh == NULL) {
            crm_config_warn("Invalid constraint '%s': No instance '%s' of '%s'", id, instance_rh,
                            id_rh);
            return FALSE;
        }
    }

    if (crm_is_true(symmetrical)) {
        crm_config_warn("The %s colocation constraint attribute has been removed."
                        "  It didn't do what you think it did anyway.", XML_CONS_ATTR_SYMMETRICAL);
    }

    if (score) {
        score_i = char2score(score);
    }

    rsc_colocation_new(id, attr, score_i, rsc_lh, rsc_rh, state_lh, state_rh, data_set);
    return TRUE;
}

static gboolean
unpack_colocation_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
{
    const char *id = NULL;
    const char *id_lh = NULL;
    const char *id_rh = NULL;
    const char *state_lh = NULL;
    const char *state_rh = NULL;

    resource_t *rsc_lh = NULL;
    resource_t *rsc_rh = NULL;

    tag_t *tag_lh = NULL;
    tag_t *tag_rh = NULL;

    xmlNode *new_xml = NULL;
    xmlNode *rsc_set_lh = NULL;
    xmlNode *rsc_set_rh = NULL;
    gboolean any_sets = FALSE;

    *expanded_xml = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    /* Attempt to expand any template/tag references in possible resource sets. */
    expand_tags_in_sets(xml_obj, &new_xml, data_set);
    if (new_xml) {
        /* There are resource sets referencing templates/tags. Return with the expanded XML. */
        crm_log_xml_trace(new_xml, "Expanded rsc_colocation...");
        *expanded_xml = new_xml;
        return TRUE;
    }

    id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE);
    id_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET);
    if (id_lh == NULL || id_rh == NULL) {
        return TRUE;
    }

    if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_lh);
        return FALSE;
    }

    if (valid_resource_or_tag(data_set, id_rh, &rsc_rh, &tag_rh) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_rh);
        return FALSE;
    }

    if (rsc_lh && rsc_rh) {
        /* Neither side references any template/tag. */
        return TRUE;
    }

    if (tag_lh && tag_rh) {
        /* A colocation constraint between two templates/tags makes no sense. */
        crm_config_err("Either LHS or RHS of %s should be a normal resource instead of a template/tag",
                       id);
        return FALSE;
    }

    state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE);
    state_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE);

    new_xml = copy_xml(xml_obj);

    /* Convert the template/tag reference in "rsc" into a resource_set under the colocation constraint. */
    if (tag_to_set(new_xml, &rsc_set_lh, XML_COLOC_ATTR_SOURCE, TRUE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_lh) {
        if (state_lh) {
            /* A "rsc-role" is specified.
               Move it into the converted resource_set as a "role"" attribute. */
            crm_xml_add(rsc_set_lh, "role", state_lh);
            xml_remove_prop(new_xml, XML_COLOC_ATTR_SOURCE_ROLE);
        }
        any_sets = TRUE;
    }

    /* Convert the template/tag reference in "with-rsc" into a resource_set under the colocation constraint. */
    if (tag_to_set(new_xml, &rsc_set_rh, XML_COLOC_ATTR_TARGET, TRUE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_rh) {
        if (state_rh) {
            /* A "with-rsc-role" is specified.
               Move it into the converted resource_set as a "role"" attribute. */
            crm_xml_add(rsc_set_rh, "role", state_rh);
            xml_remove_prop(new_xml, XML_COLOC_ATTR_TARGET_ROLE);
        }
        any_sets = TRUE;
    }

    if (any_sets) {
        crm_log_xml_trace(new_xml, "Expanded rsc_colocation...");
        *expanded_xml = new_xml;
    } else {
        free_xml(new_xml);
    }

    return TRUE;
}

gboolean
unpack_rsc_colocation(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    int score_i = 0;
    xmlNode *set = NULL;
    xmlNode *last = NULL;
    gboolean any_sets = FALSE;

    xmlNode *orig_xml = NULL;
    xmlNode *expanded_xml = NULL;

    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);

    gboolean rc = TRUE;

    if (score) {
        score_i = char2score(score);
    }

    rc = unpack_colocation_tags(xml_obj, &expanded_xml, data_set);
    if (expanded_xml) {
        orig_xml = xml_obj;
        xml_obj = expanded_xml;

    } else if (rc == FALSE) {
        return FALSE;
    }

    for (set = __xml_first_child_element(xml_obj); set != NULL;
         set = __xml_next_element(set)) {

        if (crm_str_eq((const char *)set->name, XML_CONS_TAG_RSC_SET, TRUE)) {
            any_sets = TRUE;
            set = expand_idref(set, data_set->input);
            if (unpack_colocation_set(set, score_i, data_set) == FALSE) {
                return FALSE;

            } else if (last && colocate_rsc_sets(id, last, set, score_i, data_set) == FALSE) {
                return FALSE;
            }
            last = set;
        }
    }

    if (expanded_xml) {
        free_xml(expanded_xml);
        xml_obj = orig_xml;
    }

    if (any_sets == FALSE) {
        return unpack_simple_colocation(xml_obj, data_set);
    }

    return TRUE;
}

gboolean
rsc_ticket_new(const char *id, resource_t * rsc_lh, ticket_t * ticket,
               const char *state_lh, const char *loss_policy, pe_working_set_t * data_set)
{
    rsc_ticket_t *new_rsc_ticket = NULL;

    if (rsc_lh == NULL) {
        crm_config_err("No resource found for LHS %s", id);
        return FALSE;
    }

    new_rsc_ticket = calloc(1, sizeof(rsc_ticket_t));
    if (new_rsc_ticket == NULL) {
        return FALSE;
    }

    if (state_lh == NULL || safe_str_eq(state_lh, RSC_ROLE_STARTED_S)) {
        state_lh = RSC_ROLE_UNKNOWN_S;
    }

    new_rsc_ticket->id = id;
    new_rsc_ticket->ticket = ticket;
    new_rsc_ticket->rsc_lh = rsc_lh;
    new_rsc_ticket->role_lh = text2role(state_lh);

    if (safe_str_eq(loss_policy, "fence")) {
        if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
            new_rsc_ticket->loss_policy = loss_ticket_fence;
        } else {
            crm_config_err("Resetting %s loss-policy to 'stop': fencing is not configured",
                           ticket->id);
            loss_policy = "stop";
        }
    }

    if (new_rsc_ticket->loss_policy == loss_ticket_fence) {
        crm_debug("On loss of ticket '%s': Fence the nodes running %s (%s)",
                  new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                  role2text(new_rsc_ticket->role_lh));

    } else if (safe_str_eq(loss_policy, "freeze")) {
        crm_debug("On loss of ticket '%s': Freeze %s (%s)",
                  new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                  role2text(new_rsc_ticket->role_lh));
        new_rsc_ticket->loss_policy = loss_ticket_freeze;

    } else if (safe_str_eq(loss_policy, "demote")) {
        crm_debug("On loss of ticket '%s': Demote %s (%s)",
                  new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                  role2text(new_rsc_ticket->role_lh));
        new_rsc_ticket->loss_policy = loss_ticket_demote;

    } else if (safe_str_eq(loss_policy, "stop")) {
        crm_debug("On loss of ticket '%s': Stop %s (%s)",
                  new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                  role2text(new_rsc_ticket->role_lh));
        new_rsc_ticket->loss_policy = loss_ticket_stop;

    } else {
        if (new_rsc_ticket->role_lh == RSC_ROLE_MASTER) {
            crm_debug("On loss of ticket '%s': Default to demote %s (%s)",
                      new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                      role2text(new_rsc_ticket->role_lh));
            new_rsc_ticket->loss_policy = loss_ticket_demote;

        } else {
            crm_debug("On loss of ticket '%s': Default to stop %s (%s)",
                      new_rsc_ticket->ticket->id, new_rsc_ticket->rsc_lh->id,
                      role2text(new_rsc_ticket->role_lh));
            new_rsc_ticket->loss_policy = loss_ticket_stop;
        }
    }

    pe_rsc_trace(rsc_lh, "%s (%s) ==> %s", rsc_lh->id, role2text(new_rsc_ticket->role_lh),
                 ticket->id);

    rsc_lh->rsc_tickets = g_list_append(rsc_lh->rsc_tickets, new_rsc_ticket);

    data_set->ticket_constraints = g_list_append(data_set->ticket_constraints, new_rsc_ticket);

    if (new_rsc_ticket->ticket->granted == FALSE || new_rsc_ticket->ticket->standby) {
        rsc_ticket_constraint(rsc_lh, new_rsc_ticket, data_set);
    }

    return TRUE;
}

static gboolean
unpack_rsc_ticket_set(xmlNode * set, ticket_t * ticket, const char *loss_policy,
                      pe_working_set_t * data_set)
{
    xmlNode *xml_rsc = NULL;
    resource_t *resource = NULL;
    const char *set_id = NULL;
    const char *role = NULL;

    CRM_CHECK(set != NULL, return FALSE);
    CRM_CHECK(ticket != NULL, return FALSE);

    set_id = ID(set);
    if (set_id == NULL) {
        crm_config_err("resource_set must have an id");
        return FALSE;
    }

    role = crm_element_value(set, "role");

    for (xml_rsc = first_named_child(set, XML_TAG_RESOURCE_REF);
         xml_rsc != NULL; xml_rsc = crm_next_same_xml(xml_rsc)) {

        EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc));
        pe_rsc_trace(resource, "Resource '%s' depends on ticket '%s'",
                     resource->id, ticket->id);
        rsc_ticket_new(set_id, resource, ticket, role, loss_policy, data_set);
    }

    return TRUE;
}

static gboolean
unpack_simple_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *ticket_str = crm_element_value(xml_obj, XML_TICKET_ATTR_TICKET);
    const char *loss_policy = crm_element_value(xml_obj, XML_TICKET_ATTR_LOSS_POLICY);

    ticket_t *ticket = NULL;

    const char *id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE);
    const char *state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE);
    const char *instance_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_INSTANCE);

    resource_t *rsc_lh = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No rsc_ticket constraint object to process.");
        return FALSE;
    }

    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    if (ticket_str == NULL) {
        crm_config_err("Invalid constraint '%s': No ticket specified", id);
        return FALSE;
    } else {
        ticket = g_hash_table_lookup(data_set->tickets, ticket_str);
    }

    if (ticket == NULL) {
        crm_config_err("Invalid constraint '%s': No ticket named '%s'", id, ticket_str);
        return FALSE;
    }

    if (id_lh == NULL) {
        crm_config_err("Invalid constraint '%s': No resource specified", id);
        return FALSE;
    } else {
        rsc_lh = pe_find_constraint_resource(data_set->resources, id_lh);
    }

    if (rsc_lh == NULL) {
        crm_config_err("Invalid constraint '%s': No resource named '%s'", id, id_lh);
        return FALSE;

    } else if (instance_lh && pe_rsc_is_clone(rsc_lh) == FALSE) {
        crm_config_err
            ("Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
             id, id_lh, instance_lh);
        return FALSE;
    }

    if (instance_lh) {
        rsc_lh = find_clone_instance(rsc_lh, instance_lh, data_set);
        if (rsc_lh == NULL) {
            crm_config_warn("Invalid constraint '%s': No instance '%s' of '%s'", id, instance_lh,
                            id_lh);
            return FALSE;
        }
    }

    rsc_ticket_new(id, rsc_lh, ticket, state_lh, loss_policy, data_set);
    return TRUE;
}

static gboolean
unpack_rsc_ticket_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_t * data_set)
{
    const char *id = NULL;
    const char *id_lh = NULL;
    const char *state_lh = NULL;

    resource_t *rsc_lh = NULL;
    tag_t *tag_lh = NULL;

    xmlNode *new_xml = NULL;
    xmlNode *rsc_set_lh = NULL;
    gboolean any_sets = FALSE;

    *expanded_xml = NULL;

    if (xml_obj == NULL) {
        crm_config_err("No constraint object to process.");
        return FALSE;
    }

    id = crm_element_value(xml_obj, XML_ATTR_ID);
    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    /* Attempt to expand any template/tag references in possible resource sets. */
    expand_tags_in_sets(xml_obj, &new_xml, data_set);
    if (new_xml) {
        /* There are resource sets referencing templates/tags. Return with the expanded XML. */
        crm_log_xml_trace(new_xml, "Expanded rsc_ticket...");
        *expanded_xml = new_xml;
        return TRUE;
    }

    id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE);
    if (id_lh == NULL) {
        return TRUE;
    }

    if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
        crm_config_err("Constraint '%s': Invalid reference to '%s'", id, id_lh);
        return FALSE;

    } else if (rsc_lh) {
        /* No template/tag is referenced. */
        return TRUE;
    }

    state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE);

    new_xml = copy_xml(xml_obj);

    /* Convert the template/tag reference in "rsc" into a resource_set under the rsc_ticket constraint. */
    if (tag_to_set(new_xml, &rsc_set_lh, XML_COLOC_ATTR_SOURCE, FALSE, data_set) == FALSE) {
        free_xml(new_xml);
        return FALSE;
    }

    if (rsc_set_lh) {
        if (state_lh) {
            /* A "rsc-role" is specified.
               Move it into the converted resource_set as a "role"" attribute. */
            crm_xml_add(rsc_set_lh, "role", state_lh);
            xml_remove_prop(new_xml, XML_COLOC_ATTR_SOURCE_ROLE);
        }
        any_sets = TRUE;
    }

    if (any_sets) {
        crm_log_xml_trace(new_xml, "Expanded rsc_ticket...");
        *expanded_xml = new_xml;
    } else {
        free_xml(new_xml);
    }

    return TRUE;
}

gboolean
unpack_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set)
{
    xmlNode *set = NULL;
    gboolean any_sets = FALSE;

    const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
    const char *ticket_str = crm_element_value(xml_obj, XML_TICKET_ATTR_TICKET);
    const char *loss_policy = crm_element_value(xml_obj, XML_TICKET_ATTR_LOSS_POLICY);

    ticket_t *ticket = NULL;

    xmlNode *orig_xml = NULL;
    xmlNode *expanded_xml = NULL;

    gboolean rc = TRUE;

    if (xml_obj == NULL) {
        crm_config_err("No rsc_ticket constraint object to process.");
        return FALSE;
    }

    if (id == NULL) {
        crm_config_err("%s constraint must have an id", crm_element_name(xml_obj));
        return FALSE;
    }

    if (data_set->tickets == NULL) {
        data_set->tickets =
            g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, destroy_ticket);
    }

    if (ticket_str == NULL) {
        crm_config_err("Invalid constraint '%s': No ticket specified", id);
        return FALSE;
    } else {
        ticket = g_hash_table_lookup(data_set->tickets, ticket_str);
    }

    if (ticket == NULL) {
        ticket = ticket_new(ticket_str, data_set);
        if (ticket == NULL) {
            return FALSE;
        }
    }

    rc = unpack_rsc_ticket_tags(xml_obj, &expanded_xml, data_set);
    if (expanded_xml) {
        orig_xml = xml_obj;
        xml_obj = expanded_xml;

    } else if (rc == FALSE) {
        return FALSE;
    }

    for (set = __xml_first_child_element(xml_obj); set != NULL;
         set = __xml_next_element(set)) {

        if (crm_str_eq((const char *)set->name, XML_CONS_TAG_RSC_SET, TRUE)) {
            any_sets = TRUE;
            set = expand_idref(set, data_set->input);
            if (unpack_rsc_ticket_set(set, ticket, loss_policy, data_set) == FALSE) {
                return FALSE;
            }
        }
    }

    if (expanded_xml) {
        free_xml(expanded_xml);
        xml_obj = orig_xml;
    }

    if (any_sets == FALSE) {
        return unpack_simple_rsc_ticket(xml_obj, data_set);
    }

    return TRUE;
}

gboolean
is_active(pe__location_t *cons)
{
    return TRUE;
}
