'Handle update to a trunk in (at most) three neutron calls.
Call #1) Update all changed properties but \'sub_ports\'.
PUT /v2.0/trunks/TRUNK_ID
openstack network trunk set
Call #2) Delete subports not needed anymore.
PUT /v2.0/trunks/TRUNK_ID/remove_subports
openstack network trunk unset --subport
Call #3) Create new subports.
PUT /v2.0/trunks/TRUNK_ID/add_subports
openstack network trunk set --subport
A single neutron port cannot be two subports at the same time (ie.
have two segmentation (type, ID)s on the same trunk or to belong to
two trunks). Therefore we have to delete old subports before creating
new ones to avoid conflicts.'

def handle_update(self, json_snippet, tmpl_diff, prop_diff):

    LOG.debug('attempt    to    update    trunk    %s', self.resource_id)
    def dict2frozenset(d):
        "Convert    a    dict    to    a    frozenset.\n\n                                                Create    an    immutable    equivalent    of    a    dict,    so    it's    hashable\n                                                therefore    can    be    used    as    an    element    of    a    set    or    a    key    of    another\n                                                dictionary.\n                                                "
        return frozenset(d.items())
    if ('sub_ports' in prop_diff):
        del prop_diff['sub_ports']
    sub_ports_prop_old = (self.properties[self.SUB_PORTS] or [])
    sub_ports_prop_new = (json_snippet.properties(self.properties_schema)[self.SUB_PORTS] or [])
    subports_old = {dict2frozenset(d): d for d in sub_ports_prop_old}
    subports_new = {dict2frozenset(d): d for d in sub_ports_prop_new}
    old_set = set(subports_old.keys())
    new_set = set(subports_new.keys())
    delete = (old_set - new_set)
    create = (new_set - old_set)
    dicts_delete = [subports_old[fs] for fs in delete]
    dicts_create = [subports_new[fs] for fs in create]
    LOG.debug('attempt    to    delete    subports    of    trunk    %s:    %s', self.resource_id, dicts_delete)
    LOG.debug('attempt    to    create    subports    of    trunk    %s:    %s', self.resource_id, dicts_create)
    if prop_diff:
        self.prepare_update_properties(prop_diff)
        self.client().update_trunk(self.resource_id, {'trunk': prop_diff})
    if dicts_delete:
        delete_body = self.prepare_trunk_remove_subports_body(dicts_delete)
        self.client().trunk_remove_subports(self.resource_id, delete_body)
    if dicts_create:
        create_body = self.prepare_trunk_add_subports_body(dicts_create)
        self.client().trunk_add_subports(self.resource_id, create_body)
