inline std::vector<std::set<int> >
extract_layer(connectivity_extraction& ce, std::vector<std::string>& net_ids,
              connectivity_database& connectivity, polygon_set& layout,
              std::string layer) {
  for(connectivity_database::iterator itr = connectivity.begin(); itr != connectivity.end(); ++itr) {
    net_ids.push_back((*itr).first);
    ce.insert((*itr).second[layer]);
  }
  std::vector<polygon> polygons;
  layout.get_polygons(polygons);
  for(std::size_t i = 0; i < polygons.size(); ++i) {
    ce.insert(polygons[i]);
  }
  std::vector<std::set<int> > graph(polygons.size() + net_ids.size(), std::set<int>());
  ce.extract(graph);
  return graph;
}
inline void connect_layout_to_layer(connectivity_database& connectivity, polygon_set& layout, std::string layout_layer, std::string layer, std::string net_prefix, int& net_suffix) {
  if(layout_layer.empty())
    return;
  boost::polygon::connectivity_extraction_90<int> ce;
  std::vector<std::string> net_ids;
  for(connectivity_database::iterator itr = connectivity.begin(); itr != connectivity.end(); ++itr) {
    net_ids.push_back((*itr).first);
    ce.insert((*itr).second[layer]);
  }
  std::vector<polygon> polygons;
  layout.get_polygons(polygons);
  std::size_t polygon_id_offset = net_ids.size();
  for(std::size_t i = 0; i < polygons.size(); ++i) {
    ce.insert(polygons[i]);
  }
  std::vector<std::set<int> > graph(polygons.size() + net_ids.size(), std::set<int>());
  ce.extract(graph);
  std::vector<int> polygon_color(polygons.size() + net_ids.size(), 0);
  //for each net in net_ids populate connected component with net
  for(std::size_t node_id = 0; node_id < net_ids.size(); ++node_id) {
    populate_connected_component(connectivity, polygons, polygon_color, graph, node_id, 
                                 polygon_id_offset, net_ids[node_id], net_ids, 
                                 net_prefix, layout_layer);
  }
  //for each polygon_color that is zero populate connected compontent with net_prefix + net_suffix++
  for(std::size_t i = 0; i < polygons.size(); ++i) {
    if(polygon_color[i + polygon_id_offset] == 0) {
      std::stringstream ss(std::stringstream::in | std::stringstream::out);
      ss << net_prefix << net_suffix++;
      std::string internal_net; 
      ss >> internal_net;
      populate_connected_component(connectivity, polygons, polygon_color, graph, 
                                   i + polygon_id_offset, 
                                   polygon_id_offset, internal_net, net_ids, 
                                   net_prefix, layout_layer);
    }
  }
inline void populate_connected_component
(connectivity_database& connectivity, std::vector<polygon>& polygons, 
 std::vector<int> polygon_color, std::vector<std::set<int> >& graph, 
 std::size_t node_id, std::size_t polygon_id_offset, std::string& net, 
 std::vector<std::string>& net_ids, std::string net_prefix,
 std::string& layout_layer) {
  if(polygon_color[node_id] == 1)
    return;
  polygon_color[node_id] = 1;
  if(node_id < polygon_id_offset && net_ids[node_id] != net) {
    //merge nets in connectivity database
    //if one of the nets is internal net merge it into the other
    std::string net1 = net_ids[node_id];
    std::string net2 = net;
    if(net.compare(0, net_prefix.length(), net_prefix) == 0) {
      net = net1;
      std::swap(net1, net2);
    } else {
      net_ids[node_id] = net;
    }
    connectivity_database::iterator itr = connectivity.find(net1);
    if(itr != connectivity.end()) {
      for(layout_database::iterator itr2 = (*itr).second.begin();
          itr2 != (*itr).second.end(); ++itr2) {
        connectivity[net2][(*itr2).first].insert((*itr2).second);
      }
      connectivity.erase(itr);
    }
  }
  if(node_id >= polygon_id_offset)
    connectivity[net][layout_layer].insert(polygons[node_id - polygon_id_offset]);
  for(std::set<int>::iterator itr = graph[node_id].begin();
      itr != graph[node_id].end(); ++itr) {
    populate_connected_component(connectivity, polygons, polygon_color, graph, 
                                 *itr, polygon_id_offset, net, net_ids, net_prefix, layout_layer);
  }
}