def partition_vifs(xapi_client, interfaces, security_group_states):
added = []<EOL>updated = []<EOL>removed = []<EOL>for vif in interfaces:<EOL><INDENT>if ('<STR_LIT>' in CONF.QUARK.environment_capabilities and<EOL>is_isonet_vif(vif)):<EOL><INDENT>continue<EOL><DEDENT>vif_has_groups = vif in security_group_states<EOL>if vif.tagged and vif_has_groups andsecurity_group_states[vif][sg_cli.SECURITY_GROUP_ACK]:<EOL><INDENT>continue<EOL><DEDENT>if vif.tagged:<EOL><INDENT>if vif_has_groups:<EOL><INDENT>updated.append(vif)<EOL><DEDENT>else:<EOL><INDENT>removed.append(vif)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if vif_has_groups:<EOL><INDENT>added.append(vif)<EOL><DEDENT><DEDENT><DEDENT>return added, updated, removed<EOL>
Splits VIFs into three explicit categories and one implicit

    Added - Groups exist in Redis that have not been ack'd and the VIF
            is not tagged.
            Action: Tag the VIF and apply flows
    Updated - Groups exist in Redis that have not been ack'd and the VIF
              is already tagged
              Action: Do not tag the VIF, do apply flows
    Removed - Groups do NOT exist in Redis but the VIF is tagged
              Action: Untag the VIF, apply default flows
    Self-Heal - Groups are ack'd in Redis but the VIF is untagged. We treat
                this case as if it were an "added" group.
                Action: Tag the VIF and apply flows
    NOOP - The VIF is not tagged and there are no matching groups in Redis.
           This is our implicit category
           Action: Do nothing