// File: BUSEC[P]RPKI_Downgrade_Detector/./exp.cpp
// Function: UnknownToInvalid(ROAGroup*, ROAGroup*, std::vector<ROA*, std::allocator<ROA*>>*)
vector<UnknownToInvalidDowngrade> UnknownToInvalid( ROAGroup* newPrefixes, ROAGroup* oldPrefixes, vector<ROA*>* rNews){
  vector<UnknownToInvalidDowngrade> downgrades;
  
  unordered_map<int, PrefixRange*> notValidToValidPrefixes; // This map is every Prefix which was invalid/unknown in old and is valid in new
  NotValidToValid( *newPrefixes, *oldPrefixes, &notValidToValidPrefixes);

  // Find those AS \in A, where A is all the ASes which created newly valid prefixes.
  // A should just much smaller than the set of all ASes.
  vector<int> A;

  // Save all the keys of notValidToValidPrefixes, done to maintain consistant notion between paper and program. A = notValidToValidPrefixes.keys()
  for(unordered_map<int,PrefixRange*>::iterator i = notValidToValidPrefixes.begin(); i != notValidToValidPrefixes.end(); ++i) A.push_back(i->first);
  
  vector<ROA*> rNewlyValid;
  map<ROA*, PrefixRange*> unknownToKnownByR;
  // Compute all the ROAs that creately newly valid prefixes, since we need to compute 
  // unknown to known to do this lets save the result and reuse it below.

  const PrefixRange* oldUnknown = oldPrefixes->getUnknown(); 

  for( ROA* r: *rNews){  
    PrefixRange* rUnknownToKnown = new PrefixRange(); // Don't free this
    UnknownToKnown( oldUnknown, *r, rUnknownToKnown);

    if( ! rUnknownToKnown->empty() ){
      unknownToKnownByR[r] = rUnknownToKnown;
      rNewlyValid.push_back(r); 
    }
  }

  for (int as: A) {

    PrefixRange complementNotValidToValidPrefixes = notValidToValidPrefixes[as]->complement();

    for( ROA* r: rNewlyValid){      
      PrefixRange* rUnknownToKnown = new PrefixRange( *unknownToKnownByR[r] );

      UnknownToInvalidDowngrade downgrade = UnknownToInvalidDowngrade(*r, *rUnknownToKnown);

      rUnknownToKnown->denseIntersectWith( complementNotValidToValidPrefixes, true);

      PrefixRange* unknownToInvalid = rUnknownToKnown;

      downgrade.addException(as, unknownToInvalid); 

      if ( ! downgrade.empty() ){
        downgrades.push_back(downgrade);
      }
    } // R.New.valid loop
  } // as loop

  //clean up
  for( ROA* r: rNewlyValid) delete unknownToKnownByR[r];

  return downgrades;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x3a0(%rbp)
movq %rdi, %rax
movq %rax, -0x398(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movb $0x0, -0x21(%rbp)
callq 0x6730
leaq -0x60(%rbp), %rdi
callq 0x6750
movq -0x10(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x6770
jmp 0x4030
movq -0x18(%rbp), %rsi
leaq -0x170(%rbp), %rdi
callq 0x6770
jmp 0x4042
leaq -0xe0(%rbp), %rdi
leaq -0x170(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x3cd0
jmp 0x405b
leaq -0x170(%rbp), %rdi
callq 0x6960
leaq -0xe0(%rbp), %rdi
callq 0x6960
leaq -0x188(%rbp), %rdi
callq 0x6a50
leaq -0x60(%rbp), %rdi
callq 0x5d70
movq %rax, -0x190(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x5dd0
movq %rax, -0x198(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x5da0
testb $0x1, %al
jne 0x40bb
jmp 0x4159
leaq -0x190(%rbp), %rdi
callq 0x5e00
movq %rax, %rsi
leaq -0x188(%rbp), %rdi
callq 0x6a70
jmp 0x40d8
jmp 0x40da
leaq -0x190(%rbp), %rdi
callq 0x5e60
jmp 0x408f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x4795
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x4131
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x170(%rbp), %rdi
callq 0x6960
leaq -0xe0(%rbp), %rdi
callq 0x6960
jmp 0x4795
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x4789
leaq -0x1b0(%rbp), %rdi
callq 0x6ae0
leaq -0x1e0(%rbp), %rdi
callq 0x6b00
movq -0x18(%rbp), %rdi
callq 0x5e90
movq %rax, -0x3a8(%rbp)
jmp 0x4183
movq -0x3a8(%rbp), %rax
movq %rax, -0x1e8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x6b20
movq %rax, -0x1f8(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x6b50
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x6b80
testb $0x1, %al
jne 0x41de
jmp 0x4359
leaq -0x1f8(%rbp), %rdi
callq 0x6bc0
movq (%rax), %rax
movq %rax, -0x208(%rbp)
movl $0x18, %edi
callq 0x3270
movq %rax, -0x3b0(%rbp)
jmp 0x4207
movq -0x3b0(%rbp), %rdi
callq 0x5fd0
jmp 0x4215
movq -0x3b0(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x1e8(%rbp), %rax
movq %rax, -0x3b8(%rbp)
movq -0x208(%rbp), %rsi
leaq -0x240(%rbp), %rdi
callq 0x6be0
jmp 0x4246
movq -0x3b8(%rbp), %rdi
movq -0x210(%rbp), %rdx
leaq -0x240(%rbp), %rsi
callq 0x3f50
jmp 0x4262
leaq -0x240(%rbp), %rdi
callq 0x6c30
movq -0x210(%rbp), %rdi
callq 0x62a0
movb %al, -0x3b9(%rbp)
jmp 0x4282
movb -0x3b9(%rbp), %al
testb $0x1, %al
jne 0x4346
jmp 0x4292
movq -0x210(%rbp), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x1e0(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x6c50
movq %rax, -0x3c8(%rbp)
jmp 0x42bc
movq -0x3c8(%rbp), %rax
movq -0x3d0(%rbp), %rcx
movq %rcx, (%rax)
leaq -0x1b0(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x6d30
jmp 0x42e2
jmp 0x4346
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x4771
movq -0x3b0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
movl $0x18, %esi
callq 0x3280
jmp 0x4771
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x6c30
jmp 0x4771
jmp 0x4348
leaq -0x1f8(%rbp), %rdi
callq 0x6da0
jmp 0x41c2
leaq -0x188(%rbp), %rax
movq %rax, -0x248(%rbp)
movq -0x248(%rbp), %rdi
callq 0x6dc0
movq %rax, -0x250(%rbp)
movq -0x248(%rbp), %rdi
callq 0x6df0
movq %rax, -0x258(%rbp)
leaq -0x250(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x6e20
testb $0x1, %al
jne 0x43a9
jmp 0x4672
leaq -0x250(%rbp), %rdi
callq 0x6e60
movl (%rax), %eax
movl %eax, -0x25c(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x25c(%rbp), %rsi
callq 0x6e80
movq %rax, -0x3d8(%rbp)
jmp 0x43d6
movq -0x3d8(%rbp), %rax
movq (%rax), %rsi
leaq -0x278(%rbp), %rdi
callq 0x6080
jmp 0x43ee
leaq -0x1b0(%rbp), %rax
movq %rax, -0x280(%rbp)
movq -0x280(%rbp), %rdi
callq 0x6b20
movq %rax, -0x288(%rbp)
movq -0x280(%rbp), %rdi
callq 0x6b50
movq %rax, -0x290(%rbp)
leaq -0x288(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x6b80
testb $0x1, %al
jne 0x443e
jmp 0x4644
leaq -0x288(%rbp), %rdi
callq 0x6bc0
movq (%rax), %rax
movq %rax, -0x298(%rbp)
movl $0x18, %edi
callq 0x3270
movq %rax, -0x3e0(%rbp)
jmp 0x4467
leaq -0x1e0(%rbp), %rdi
leaq -0x298(%rbp), %rsi
callq 0x6c50
movq %rax, -0x3e8(%rbp)
jmp 0x4483
movq -0x3e0(%rbp), %rdi
movq -0x3e8(%rbp), %rax
movq (%rax), %rsi
callq 0x6380
jmp 0x449b
movq -0x3e0(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movq -0x298(%rbp), %rsi
leaq -0x350(%rbp), %rdi
callq 0x6be0
jmp 0x44be
movq -0x2a0(%rbp), %rsi
leaq -0x368(%rbp), %rdi
callq 0x6380
jmp 0x44d3
leaq -0x320(%rbp), %rdi
leaq -0x350(%rbp), %rsi
leaq -0x368(%rbp), %rdx
callq 0x6eb0
jmp 0x44ef
leaq -0x368(%rbp), %rdi
callq 0x61e0
leaq -0x350(%rbp), %rdi
callq 0x6c30
movq -0x2a0(%rbp), %rdi
leaq -0x278(%rbp), %rsi
movl $0x1, %edx
callq 0x5ed0
jmp 0x4521
movq -0x2a0(%rbp), %rax
movq %rax, -0x370(%rbp)
movl -0x25c(%rbp), %esi
movq -0x370(%rbp), %rdx
leaq -0x320(%rbp), %rdi
callq 0x6f40
jmp 0x454a
leaq -0x320(%rbp), %rdi
callq 0x6fe0
movb %al, -0x3e9(%rbp)
jmp 0x455e
movb -0x3e9(%rbp), %al
testb $0x1, %al
jne 0x4627
jmp 0x456e
movq -0x3a0(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x7030
jmp 0x4583
jmp 0x4627
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x4661
movq -0x3e0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
movl $0x18, %esi
callq 0x3280
jmp 0x4661
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x45f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x368(%rbp), %rdi
callq 0x61e0
leaq -0x350(%rbp), %rdi
callq 0x6c30
jmp 0x4661
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x70a0
jmp 0x4661
leaq -0x320(%rbp), %rdi
callq 0x70a0
leaq -0x288(%rbp), %rdi
callq 0x6da0
jmp 0x4422
leaq -0x278(%rbp), %rdi
callq 0x61e0
leaq -0x250(%rbp), %rdi
callq 0x70e0
jmp 0x438d
leaq -0x278(%rbp), %rdi
callq 0x61e0
jmp 0x4771
leaq -0x1b0(%rbp), %rax
movq %rax, -0x378(%rbp)
movq -0x378(%rbp), %rdi
callq 0x6b20
movq %rax, -0x380(%rbp)
movq -0x378(%rbp), %rdi
callq 0x6b50
movq %rax, -0x388(%rbp)
leaq -0x380(%rbp), %rdi
leaq -0x388(%rbp), %rsi
callq 0x6b80
testb $0x1, %al
jne 0x46bf
jmp 0x4738
leaq -0x380(%rbp), %rdi
callq 0x6bc0
movq (%rax), %rax
movq %rax, -0x390(%rbp)
leaq -0x1e0(%rbp), %rdi
leaq -0x390(%rbp), %rsi
callq 0x6c50
movq %rax, -0x3f8(%rbp)
jmp 0x46f1
movq -0x3f8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x400(%rbp)
cmpq $0x0, %rax
je 0x4725
movq -0x400(%rbp), %rdi
callq 0x61e0
movq -0x400(%rbp), %rdi
movl $0x18, %esi
callq 0x3280
jmp 0x4727
leaq -0x380(%rbp), %rdi
callq 0x6da0
jmp 0x46a6
movb $0x1, -0x21(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x7100
leaq -0x1b0(%rbp), %rdi
callq 0x7120
leaq -0x188(%rbp), %rdi
callq 0x7180
leaq -0x60(%rbp), %rdi
callq 0x71e0
testb $0x1, -0x21(%rbp)
jne 0x47b8
jmp 0x47ac
leaq -0x1e0(%rbp), %rdi
callq 0x7100
leaq -0x1b0(%rbp), %rdi
callq 0x7120
leaq -0x188(%rbp), %rdi
callq 0x7180
leaq -0x60(%rbp), %rdi
callq 0x71e0
movq -0x3a0(%rbp), %rdi
callq 0x7200
jmp 0x47c8
movq -0x3a0(%rbp), %rdi
callq 0x7200
movq -0x398(%rbp), %rax
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
movq -0xe8(%rbp), %rdi
callq 0x3400
nopw %cs:(%rax,%rax)