docs: def update_network(network,
      update_nodes = True,
      update_links = True,
      update_groups = True,
      update_scenarios = True,
      **kwargs):
      """
          Update an entire network
      """
      log.info("Updating Network %s", network.name)
      user_id = kwargs.get('user_id')
      #check_perm('update_network')
  
      try:
          net_i = db.DBSession.query(Network).filter(Network.id == network.id).one()
      except NoResultFound:
          raise ResourceNotFoundError("Network with id %s not found"%(network.id))
  
      net_i.project_id          = network.project_id
      net_i.name                = network.name
      net_i.description         = network.description
      net_i.projection          = network.projection
      net_i.layout              = network.get_layout()
  
      all_resource_attrs = {}
      new_network_attributes = _update_attributes(net_i, network.attributes)
      all_resource_attrs.update(new_network_attributes)
      hdb.add_resource_types(net_i, network.types)
  
      #Maps temporary node_ids to real node_ids
      node_id_map = dict()
  
      if network.nodes is not None and update_nodes is True:
          log.info("Updating nodes")
          t0 = time.time()
          #First add all the nodes
          node_id_map = dict([(n.id, n) for n in net_i.nodes])
          for node in network.nodes:
              #If we get a negative or null node id, we know
              #it is a new node.
              if node.id is not None and node.id > 0:
                  n = node_id_map[node.id]
                  n.name        = node.name
                  n.description = node.description
                  n.x           = node.x
                  n.y           = node.y
                  n.status      = node.status
                  n.layout      = node.get_layout()
              else:
                  log.info("Adding new node %s", node.name)
                  n = net_i.add_node(node.name,
                                     node.description,
                                     node.get_layout(),
                                     node.x,
                                     node.y)
                  net_i.nodes.append(n)
                  node_id_map[n.id] = n
  
              all_resource_attrs.update(_update_attributes(n, node.attributes))
              hdb.add_resource_types(n, node.types)
          log.info("Updating nodes took %s", time.time() - t0)
  
      link_id_map = dict()
      if network.links is not None and update_links is True:
          log.info("Updating links")
          t0 = time.time()
          link_id_map = dict([(l.link_id, l) for l in net_i.links])
          for link in network.links:
              node_1 = node_id_map[link.node_1_id]
  
              node_2 = node_id_map[link.node_2_id]
  
              if link.id is None or link.id < 0:
                  log.info("Adding new link %s", link.name)
                  l = net_i.add_link(link.name,
                                     link.description,
                                     link.get_layout(),
                                     node_1,
                                     node_2)
                  net_i.links.append(l)
                  link_id_map[link.id] = l
              else:
                  l = link_id_map[link.id]
                  l.name       = link.name
                  l.link_descripion = link.description
                  l.node_a          = node_1
                  l.node_b          = node_2
                  l.layout          = link.get_layout()
  
  
              all_resource_attrs.update(_update_attributes(l, link.attributes))
              hdb.add_resource_types(l, link.types)
          log.info("Updating links took %s", time.time() - t0)
  
      group_id_map = dict()
      #Next all the groups
      if network.resourcegroups is not None and update_groups is True:
          log.info("Updating groups")
          t0 = time.time()
          group_id_map = dict([(g.group_id, g) for g in net_i.resourcegroups])
          for group in network.resourcegroups:
              #If we get a negative or null group id, we know
              #it is a new group.
              if group.id is not None and group.id > 0:
                  g_i = group_id_map[group.id]
                  g_i.name        = group.name
                  g_i.description = group.description
                  g_i.status           = group.status
              else:
                  log.info("Adding new group %s", group.name)
                  g_i = net_i.add_group(group.name,
                                     group.description,
                                     group.status)
                  net_i.resourcegroups.append(net_i)
                  group_id_map[g_i.group_id] = g_i
  
              all_resource_attrs.update(_update_attributes(g_i, group.attributes))
              hdb.add_resource_types(g_i, group.types)
              group_id_map[group.id] = g_i
          log.info("Updating groups took %s", time.time() - t0)
  
      errors = []
      if network.scenarios is not None and update_scenarios is True:
          for s in network.scenarios:
              add_scenario = False
              if s.id is not None:
                  if s.id > 0:
                      try:
                          scen_i = db.DBSession.query(Scenario).filter(Scenario.id==s.id).one()
                          if scen_i.locked == 'Y':
                              errors.append('Scenario %s was not updated as it is locked'%(s.id))
                              continue
  
                          scenario.update_scenario(s, flush=False, **kwargs)
                      except NoResultFound:
                          raise ResourceNotFoundError("Scenario %s not found"%(s.id))
                  else:
                      add_scenario = True
              else:
                  add_scenario = True
  
              if add_scenario is True:
                  log.info("Adding new scenario %s to network", s.name)
                  scenario.add_scenario(network.id, s, **kwargs)
  
      db.DBSession.flush()
  
      updated_net = get_network(network.id, summary=True, **kwargs)
      return updated_net