// File: kulpreet[P]lightning-network-graph-analysis/src/include/algos.hpp
// Function: lncentrality::find_non_singleton_components(std::vector<unsigned long, std::allocator<unsigned long>>&, boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, lncentrality::LitVertex, lncentrality::LitEdge, boost::no_property, boost::listS>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
void find_non_singleton_components(std::vector<Vertex> &art_points, LitGraph &g,
                                   string &stem, string &outdir) {

  // make a map component id to component size
  std::map<int, int> component_sizes;
  std::vector<Vertex>::iterator i;
  std::ofstream out;

  graph_traits<LitGraph>::edge_iterator ei, ei_end;
  graph_traits<LitGraph>::out_edge_iterator out_i, out_end;

  typedef graph_traits<LitGraph>::edge_descriptor Edge;
  std::vector<Edge> bridges;
  std::set<int> component_ids;
  std::map<int, set<int>> interesting_art_points;
  int num_interesting;

  // find the size of components by iterating over all edges.
  for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    component_sizes[g[*ei].component]++;
  }

  // iterate over all edges again and select those edges where
  // component size on both vertices are greater than 1. This and the
  // previous loop can probably be optimised.
  for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    if (component_sizes[g[*ei].component] == 1) {
      bridges.push_back(*ei);
    }
  }

  // iterate over all art points
  for (i = art_points.begin(); i != art_points.end(); i++) {
    // get all the components for all the edges of the art points
    component_ids.clear();
    for (boost::tie(out_i, out_end) = out_edges(*i, g); out_i != out_end;
         ++out_i) {
      component_ids.insert(g[*out_i].component);
    }
    // find the number of components the art point is connecting
    num_interesting =
        std::accumulate(component_ids.begin(), component_ids.end(), 0,
                        [&component_sizes](int a, int cid) {
                          if (component_sizes[cid] > 5) {
                            a = a + 1;
                          }
                          return a;
                        });
    // change the min size of components to consider "interesting"
    if (num_interesting > 1) {
      interesting_art_points[*i] = component_ids;
    }
  }

  // date, #components, #interesting art points. No header output as
  // this is appended to file.
  out.open(outdir + "/key_ap_stats.csv", std::fstream::out | std::fstream::app);
  out << stem << "," << component_sizes.size() << ","
      << interesting_art_points.size() << std::endl;
  out.close();

  out.open(outdir + "/" + stem + ".key_ap.csv",
           std::fstream::out | std::fstream::trunc);

  // Key Articulation Points. Header included.
  out << "alias,num components,degree,pub_key" << std::endl;
  for (std::map<int, set<int>>::iterator x = interesting_art_points.begin();
       x != interesting_art_points.end(); x++) {
    out << "\"" << g[x->first].name << "\""
        << "," << (x->second).size() << "," << degree(x->first, g) << ","
        << g[x->first].pub_key << endl;
  }
  out.close();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x630, %rsp            # imm = 0x630
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xf3d0
leaq -0x58(%rbp), %rdi
callq 0xf3f0
leaq -0x258(%rbp), %rdi
callq 0xa760
jmp 0xba0b
leaq -0x270(%rbp), %rdi
callq 0xe3f0
jmp 0xba19
leaq -0x278(%rbp), %rdi
callq 0xe3f0
jmp 0xba27
leaq -0x288(%rbp), %rdi
callq 0xf410
jmp 0xba35
leaq -0x298(%rbp), %rdi
callq 0xf410
jmp 0xba43
leaq -0x2b0(%rbp), %rdi
callq 0xf430
leaq -0x2e0(%rbp), %rdi
callq 0xf450
leaq -0x310(%rbp), %rdi
callq 0xf470
movq -0x10(%rbp), %rdi
callq 0xe410
movq %rdx, -0x4d8(%rbp)
movq %rax, -0x4d0(%rbp)
jmp 0xba80
movq -0x4d8(%rbp), %rax
movq -0x4d0(%rbp), %rcx
movq %rcx, -0x328(%rbp)
movq %rax, -0x320(%rbp)
leaq -0x338(%rbp), %rdi
leaq -0x270(%rbp), %rsi
leaq -0x278(%rbp), %rdx
callq 0xe490
jmp 0xbab8
leaq -0x338(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0xe4d0
jmp 0xbacd
jmp 0xbacf
leaq -0x270(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0xe500
movb %al, -0x4d9(%rbp)
jmp 0xbaea
movb -0x4d9(%rbp), %al
testb $0x1, %al
jne 0xbaf9
jmp 0xbbcc
movq -0x10(%rbp), %rax
movq %rax, -0x4e8(%rbp)
leaq -0x350(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0xe560
jmp 0xbb19
movq -0x4e8(%rbp), %rdi
movq -0x340(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movups -0x350(%rbp), %xmm0
movups %xmm0, (%rax)
callq 0xe640
movq %rax, -0x4f0(%rbp)
jmp 0xbb46
movq -0x4f0(%rbp), %rsi
addq $0xd8, %rsi
leaq -0x50(%rbp), %rdi
callq 0xf490
movq %rax, -0x4f8(%rbp)
jmp 0xbb66
movq -0x4f8(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
leaq -0x270(%rbp), %rdi
callq 0xe6b0
jmp 0xbb82
jmp 0xbacf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0xc446
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0xc43a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0xc416
movq -0x10(%rbp), %rdi
callq 0xe410
movq %rdx, -0x508(%rbp)
movq %rax, -0x500(%rbp)
jmp 0xbbe5
movq -0x508(%rbp), %rax
movq -0x500(%rbp), %rcx
movq %rcx, -0x360(%rbp)
movq %rax, -0x358(%rbp)
leaq -0x370(%rbp), %rdi
leaq -0x270(%rbp), %rsi
leaq -0x278(%rbp), %rdx
callq 0xe490
jmp 0xbc1d
leaq -0x370(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0xe4d0
jmp 0xbc32
jmp 0xbc34
leaq -0x270(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0xe500
movb %al, -0x509(%rbp)
jmp 0xbc4f
movb -0x509(%rbp), %al
testb $0x1, %al
jne 0xbc5e
jmp 0xbd18
movq -0x10(%rbp), %rax
movq %rax, -0x518(%rbp)
leaq -0x388(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0xe560
jmp 0xbc7e
movq -0x518(%rbp), %rdi
movq -0x378(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movups -0x388(%rbp), %xmm0
movups %xmm0, (%rax)
callq 0xe640
movq %rax, -0x520(%rbp)
jmp 0xbcab
movq -0x520(%rbp), %rsi
addq $0xd8, %rsi
leaq -0x50(%rbp), %rdi
callq 0xf490
movq %rax, -0x528(%rbp)
jmp 0xbccb
movq -0x528(%rbp), %rax
cmpl $0x1, (%rax)
jne 0xbd03
leaq -0x3a0(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0xe560
jmp 0xbcec
leaq -0x2b0(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
callq 0xf570
jmp 0xbd01
jmp 0xbd03
jmp 0xbd05
leaq -0x270(%rbp), %rdi
callq 0xe6b0
jmp 0xbd13
jmp 0xbc34
movq -0x8(%rbp), %rdi
callq 0xf350
movq %rax, -0x3a8(%rbp)
movq -0x3a8(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
callq 0xf380
movq %rax, -0x3b0(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0xf5a0
testb $0x1, %al
jne 0xbd5c
jmp 0xbf54
leaq -0x2e0(%rbp), %rdi
callq 0xf5e0
leaq -0x58(%rbp), %rdi
callq 0xf6a0
movq (%rax), %rsi
movq -0x10(%rbp), %rdx
leaq -0x3d0(%rbp), %rdi
callq 0xf600
jmp 0xbd86
leaq -0x3e0(%rbp), %rdi
leaq -0x288(%rbp), %rsi
leaq -0x298(%rbp), %rdx
callq 0xf6c0
jmp 0xbda2
leaq -0x3e0(%rbp), %rdi
leaq -0x3d0(%rbp), %rsi
callq 0xf700
jmp 0xbdb7
jmp 0xbdb9
leaq -0x288(%rbp), %rdi
leaq -0x298(%rbp), %rsi
callq 0xf740
movb %al, -0x529(%rbp)
jmp 0xbdd4
movb -0x529(%rbp), %al
testb $0x1, %al
jne 0xbde3
jmp 0xbe86
movq -0x10(%rbp), %rax
movq %rax, -0x538(%rbp)
leaq -0x3f8(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0xf7d0
jmp 0xbe03
movq -0x538(%rbp), %rdi
movq -0x3e8(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movups -0x3f8(%rbp), %xmm0
movups %xmm0, (%rax)
callq 0xe640
movq %rax, -0x540(%rbp)
jmp 0xbe30
movq -0x540(%rbp), %rsi
addq $0xd8, %rsi
leaq -0x2e0(%rbp), %rdi
callq 0xf780
movb %dl, -0x549(%rbp)
movq %rax, -0x548(%rbp)
jmp 0xbe59
movb -0x549(%rbp), %al
movq -0x548(%rbp), %rcx
movq %rcx, -0x408(%rbp)
movb %al, -0x400(%rbp)
leaq -0x288(%rbp), %rdi
callq 0xf810
jmp 0xbe81
jmp 0xbdb9
leaq -0x2e0(%rbp), %rdi
movq %rdi, -0x558(%rbp)
callq 0xf840
movq -0x558(%rbp), %rdi
movq %rax, -0x410(%rbp)
callq 0xf870
movq %rax, -0x418(%rbp)
leaq -0x50(%rbp), %rax
movq %rax, -0x420(%rbp)
movq -0x410(%rbp), %rdi
movq -0x418(%rbp), %rsi
movq -0x420(%rbp), %rcx
xorl %edx, %edx
callq 0xc460
movl %eax, -0x550(%rbp)
jmp 0xbee2
movl -0x550(%rbp), %eax
movl %eax, -0x314(%rbp)
cmpl $0x1, -0x314(%rbp)
jle 0xbf3b
leaq -0x58(%rbp), %rdi
callq 0xf6a0
movl (%rax), %eax
movl %eax, -0x424(%rbp)
leaq -0x310(%rbp), %rdi
leaq -0x424(%rbp), %rsi
callq 0xf8a0
movq %rax, -0x560(%rbp)
jmp 0xbf24
movq -0x560(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
callq 0xf980
jmp 0xbf39
jmp 0xbf3b
jmp 0xbf3d
leaq -0x58(%rbp), %rdi
xorl %esi, %esi
callq 0xf9b0
movq %rax, -0x430(%rbp)
jmp 0xbd33
movq -0x20(%rbp), %rsi
leaq 0x3f170(%rip), %rdx     # 0x4b0cf
leaq -0x450(%rbp), %rdi
callq 0xef20
jmp 0xbf6d
movl $0x10, %edi
movl $0x1, %esi
callq 0xefa0
movl %eax, -0x564(%rbp)
jmp 0xbf84
movl -0x564(%rbp), %edx
leaq -0x258(%rbp), %rdi
leaq -0x450(%rbp), %rsi
callq 0xa210
jmp 0xbf9f
leaq -0x450(%rbp), %rdi
callq 0xa2b0
movq -0x18(%rbp), %rsi
leaq -0x258(%rbp), %rdi
callq 0xa3e0
movq %rax, -0x570(%rbp)
jmp 0xbfc4
movq -0x570(%rbp), %rdi
leaq 0x3f0d1(%rip), %rsi     # 0x4b0a3
callq 0xa410
movq %rax, -0x578(%rbp)
jmp 0xbfe0
leaq -0x50(%rbp), %rdi
callq 0xf9f0
movq -0x578(%rbp), %rdi
movq %rax, %rsi
callq 0xa0c0
movq %rax, -0x580(%rbp)
jmp 0xc001
movq -0x580(%rbp), %rdi
leaq 0x3f094(%rip), %rsi     # 0x4b0a3
callq 0xa410
movq %rax, -0x588(%rbp)
jmp 0xc01d
leaq -0x310(%rbp), %rdi
callq 0xfa10
movq -0x588(%rbp), %rdi
movq %rax, %rsi
callq 0xa0c0
movq %rax, -0x590(%rbp)
jmp 0xc041
movq -0x590(%rbp), %rdi
movq 0x68f11(%rip), %rsi     # 0x74f60
callq 0xa460
jmp 0xc056
leaq -0x258(%rbp), %rdi
callq 0xa640
jmp 0xc064
movq -0x20(%rbp), %rsi
leaq 0x3f009(%rip), %rdx     # 0x4b078
leaq -0x4b0(%rbp), %rdi
callq 0xef20
jmp 0xc07d
movq -0x18(%rbp), %rdx
leaq -0x490(%rbp), %rdi
leaq -0x4b0(%rbp), %rsi
callq 0xeed0
jmp 0xc096
leaq 0x3f044(%rip), %rdx     # 0x4b0e1
leaq -0x470(%rbp), %rdi
leaq -0x490(%rbp), %rsi
callq 0xee80
jmp 0xc0b2
movl $0x10, %edi
movl $0x20, %esi
callq 0xefa0
movl %eax, -0x594(%rbp)
jmp 0xc0c9
movl -0x594(%rbp), %edx
leaq -0x258(%rbp), %rdi
leaq -0x470(%rbp), %rsi
callq 0xa210
jmp 0xc0e4
leaq -0x470(%rbp), %rdi
callq 0xa2b0
leaq -0x490(%rbp), %rdi
callq 0xa2b0
leaq -0x4b0(%rbp), %rdi
callq 0xa2b0
leaq 0x3efde(%rip), %rsi     # 0x4b0ed
leaq -0x258(%rbp), %rdi
callq 0xa410
movq %rax, -0x5a0(%rbp)
jmp 0xc124
movq -0x5a0(%rbp), %rdi
movq 0x68e2e(%rip), %rsi     # 0x74f60
callq 0xa460
jmp 0xc139
leaq -0x310(%rbp), %rdi
callq 0xfa30
movq %rax, -0x4b8(%rbp)
leaq -0x310(%rbp), %rdi
callq 0xfa90
movq %rax, -0x4c0(%rbp)
leaq -0x4b8(%rbp), %rdi
leaq -0x4c0(%rbp), %rsi
callq 0xfa60
testb $0x1, %al
jne 0xc17b
jmp 0xc3c6
leaq 0x4052e(%rip), %rsi     # 0x4c6b0
leaq -0x258(%rbp), %rdi
callq 0xa410
movq %rax, -0x5a8(%rbp)
jmp 0xc197
movq -0x10(%rbp), %rax
movq %rax, -0x5b8(%rbp)
leaq -0x4b8(%rbp), %rdi
callq 0xfac0
movq -0x5b8(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe5f0
movq %rax, -0x5b0(%rbp)
jmp 0xc1c6
movq -0x5a8(%rbp), %rdi
movq -0x5b0(%rbp), %rsi
addq $0x40, %rsi
callq 0xa3e0
movq %rax, -0x5c0(%rbp)
jmp 0xc1e6
movq -0x5c0(%rbp), %rdi
leaq 0x404bc(%rip), %rsi     # 0x4c6b0
callq 0xa410
movq %rax, -0x5c8(%rbp)
jmp 0xc202
movq -0x5c8(%rbp), %rdi
leaq 0x3ee93(%rip), %rsi     # 0x4b0a3
callq 0xa410
movq %rax, -0x5d0(%rbp)
jmp 0xc21e
leaq -0x4b8(%rbp), %rdi
callq 0xfac0
movq %rax, %rdi
addq $0x8, %rdi
callq 0xfae0
movq -0x5d0(%rbp), %rdi
movq %rax, %rsi
callq 0xa0c0
movq %rax, -0x5d8(%rbp)
jmp 0xc24e
movq -0x5d8(%rbp), %rdi
leaq 0x3ee47(%rip), %rsi     # 0x4b0a3
callq 0xa410
movq %rax, -0x5e0(%rbp)
jmp 0xc26a
leaq -0x4b8(%rbp), %rdi
callq 0xfac0
movslq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0xe5c0
movq %rax, -0x5e8(%rbp)
jmp 0xc28b
movq -0x5e8(%rbp), %rsi
movq -0x5e0(%rbp), %rdi
callq 0xa0c0
movq %rax, -0x5f0(%rbp)
jmp 0xc2a7
movq -0x5f0(%rbp), %rdi
leaq 0x3edee(%rip), %rsi     # 0x4b0a3
callq 0xa410
movq %rax, -0x5f8(%rbp)
jmp 0xc2c3
movq -0x10(%rbp), %rax
movq %rax, -0x608(%rbp)
leaq -0x4b8(%rbp), %rdi
callq 0xfac0
movq -0x608(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe5f0
movq %rax, -0x600(%rbp)
jmp 0xc2f2
movq -0x5f8(%rbp), %rdi
movq -0x600(%rbp), %rsi
addq $0x20, %rsi
callq 0xa3e0
movq %rax, -0x610(%rbp)
jmp 0xc312
movq -0x610(%rbp), %rdi
movq 0x68c40(%rip), %rsi     # 0x74f60
callq 0xa460
jmp 0xc327
jmp 0xc329
leaq -0x4b8(%rbp), %rdi
xorl %esi, %esi
callq 0xfb00
movq %rax, -0x4c8(%rbp)
jmp 0xc14c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
leaq -0x450(%rbp), %rdi
callq 0xa2b0
jmp 0xc416
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0xc3b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
jmp 0xc3ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x260(%rbp)
movl %eax, -0x264(%rbp)
leaq -0x470(%rbp), %rdi
callq 0xa2b0
leaq -0x490(%rbp), %rdi
callq 0xa2b0
leaq -0x4b0(%rbp), %rdi
callq 0xa2b0
jmp 0xc416
leaq -0x258(%rbp), %rdi
callq 0xa640
jmp 0xc3d4
leaq -0x310(%rbp), %rdi
callq 0xfb40
leaq -0x2e0(%rbp), %rdi
callq 0xfb60
leaq -0x2b0(%rbp), %rdi
callq 0xfb80
leaq -0x258(%rbp), %rdi
callq 0xa6a0
leaq -0x50(%rbp), %rdi
callq 0xfbe0
addq $0x630, %rsp            # imm = 0x630
popq %rbp
retq
leaq -0x310(%rbp), %rdi
callq 0xfb40
leaq -0x2e0(%rbp), %rdi
callq 0xfb60
leaq -0x2b0(%rbp), %rdi
callq 0xfb80
leaq -0x258(%rbp), %rdi
callq 0xa6a0
leaq -0x50(%rbp), %rdi
callq 0xfbe0
movq -0x260(%rbp), %rdi
callq 0xa7d0
nopl (%rax,%rax)