// File: Luthaf[P]zeopp/channel.cc
// Function: PORE::reconstruct()
void PORE::reconstruct(){
    vector<bool> haveVisited = vector<bool>(nodes.size(),false);
    vector<DELTA_POS> displacements = vector<DELTA_POS>(nodes.size());
    unsigned int visitCount = 0;
    
    //Search through the PORE, emphasizing nodes located in the current unit
    //cell or in previously visited unit cells. Record the unit cell within which
    //each node is encountered
    comparer = ReconstructorComparator();
    HEAP< pair<int,DELTA_POS> > stack (compareNodes);
    stack.insert(pair<int,DELTA_POS> (0, DELTA_POS(0,0,0))); // Pick the first node as the starting point
    DELTA_POS curPos = DELTA_POS(0,0,0);
    
    // Continue reconstruction until all nodes have been visited
    while(visitCount < nodes.size()){
        if(stack.size() == 0){
            cerr << "Error: Stack empties prior to pore reconstruction completion." << "\n"
            << "Please contact the source code provided with this message." << "\n"
            << "Exiting..." << "\n"
            << "Nnodes = " << nodes.size() << "  visitCount= " << visitCount << "\n";
            
            exit(1);
        }
        
        pair<int,DELTA_POS> best = stack.pop();
        
        if(!haveVisited.at(best.first)){
            visitCount++;
            haveVisited.at(best.first) = true;
            displacements.at(best.first) = best.second;
            
            // If changed unit cell, need to restructure heap
            if(!best.second.equals(curPos)){
                comparer.setPosition(best.second);
                stack.reHeapify();
                curPos = best.second;
            }
            
            // Add all the nodes from the current node to the stack that
            // have not yet been visited
            DIJKSTRA_NODE curNode = nodes.at(best.first);
            for(unsigned int j = 0; j < curNode.connections.size(); j++){
                CONN curConn = curNode.connections.at(j);
                if(!haveVisited.at(curConn.to)){
                    DELTA_POS newPos = curPos + curConn.deltaPos;
                    stack.insert(pair<int,DELTA_POS>(curConn.to,newPos));
                }
            }
        }
    }
    
    map<DELTA_POS, vector<int> ,  bool(*)(DELTA_POS,DELTA_POS)> results (fn_pt);
    
    //Store the list of nodes and unit cells in a usable format
    for(unsigned int i = 0; i < nodes.size(); i++){
        map<DELTA_POS, vector<int> >::iterator iter = results.find(displacements.at(i));
        if(iter == results.end()){
            vector<int> newList; newList.push_back(i);
            results.insert(pair<DELTA_POS, vector<int> > (displacements.at(i),newList));
        }
        else
            iter->second.push_back(i);
    }
    
    // Copy the unit cells visited and their corresponding node ids to intrinsic
    // data structures
    map<DELTA_POS, vector<int> >::iterator rIter = results.begin();
    while(rIter != results.end()){
        unitCells.push_back(rIter->first);
        ucNodes.push_back(rIter->second);
        rIter++;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x440, %rsp            # imm = 0x440
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, -0x2f0(%rbp)
movb $0x0, -0x31(%rbp)
leaq -0x32(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
callq 0x64b50
movq -0x2f0(%rbp), %rsi
movq -0x2e8(%rbp), %rcx
leaq -0x30(%rbp), %rdi
leaq -0x31(%rbp), %rdx
callq 0x64b70
jmp 0xc4a9b
leaq -0x32(%rbp), %rdi
callq 0x64bf0
movq -0x2f8(%rbp), %rdi
addq $0x60, %rdi
callq 0x10100
movq %rax, -0x308(%rbp)
leaq -0x61(%rbp), %rdi
movq %rdi, -0x300(%rbp)
callq 0x65af0
movq -0x308(%rbp), %rsi
movq -0x300(%rbp), %rdx
leaq -0x60(%rbp), %rdi
callq 0xcd810
jmp 0xc4ae4
leaq -0x61(%rbp), %rdi
callq 0x14e70
movl $0x0, -0x68(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xc8590
jmp 0xc4b02
leaq 0x1aecf7(%rip), %rdi    # 0x273800
leaq -0xa8(%rbp), %rsi
movq %rsi, -0x310(%rbp)
callq 0xcd880
movq -0x310(%rbp), %rdi
callq 0xcd7f0
leaq 0x3d41(%rip), %rsi      # 0xc8870
leaq -0xc8(%rbp), %rdi
callq 0xcd8d0
jmp 0xc4b3d
movl $0x0, -0xdc(%rbp)
leaq -0xe8(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0xc4b5b
leaq -0xd8(%rbp), %rdi
leaq -0xdc(%rbp), %rsi
leaq -0xe8(%rbp), %rdx
callq 0xcd990
jmp 0xc4b77
movq -0xd8(%rbp), %rsi
movq -0xd0(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0xcd930
jmp 0xc4b93
leaq -0xf4(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0xc4ba7
jmp 0xc4ba9
movq -0x2f8(%rbp), %rdi
movl -0x68(%rbp), %eax
movq %rax, -0x318(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, %rcx
movq -0x318(%rbp), %rax
cmpq %rcx, %rax
jae 0xc5161
leaq -0xc8(%rbp), %rdi
callq 0xcd9c0
movl %eax, -0x31c(%rbp)
jmp 0xc4bea
movl -0x31c(%rbp), %eax
cmpl $0x0, %eax
jne 0xc4d8e
movq 0x1ae3f0(%rip), %rdi    # 0x272ff0
leaq 0x136a48(%rip), %rsi    # 0x1fb64f
callq 0x5540
movq %rax, -0x328(%rbp)
jmp 0xc4c15
movq -0x328(%rbp), %rdi
leaq 0x134a02(%rip), %rsi    # 0x1f9625
callq 0x5540
movq %rax, -0x330(%rbp)
jmp 0xc4c31
movq -0x330(%rbp), %rdi
leaq 0x136a4e(%rip), %rsi    # 0x1fb68d
callq 0x5540
movq %rax, -0x338(%rbp)
jmp 0xc4c4d
movq -0x338(%rbp), %rdi
leaq 0x1349ca(%rip), %rsi    # 0x1f9625
callq 0x5540
movq %rax, -0x340(%rbp)
jmp 0xc4c69
movq -0x340(%rbp), %rdi
leaq 0x1366a3(%rip), %rsi    # 0x1fb31a
callq 0x5540
movq %rax, -0x348(%rbp)
jmp 0xc4c85
movq -0x348(%rbp), %rdi
leaq 0x134992(%rip), %rsi    # 0x1f9625
callq 0x5540
movq %rax, -0x350(%rbp)
jmp 0xc4ca1
movq -0x350(%rbp), %rdi
leaq 0x136a19(%rip), %rsi    # 0x1fb6c8
callq 0x5540
movq %rax, -0x358(%rbp)
jmp 0xc4cbd
movq -0x2f8(%rbp), %rdi
addq $0x60, %rdi
callq 0x10100
movq -0x358(%rbp), %rdi
movq %rax, %rsi
callq 0x5160
movq %rax, -0x360(%rbp)
jmp 0xc4ce5
movq -0x360(%rbp), %rdi
leaq 0x1369df(%rip), %rsi    # 0x1fb6d2
callq 0x5540
movq %rax, -0x368(%rbp)
jmp 0xc4d01
movq -0x368(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x56f0
movq %rax, -0x370(%rbp)
jmp 0xc4d19
movq -0x370(%rbp), %rdi
leaq 0x1348fe(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0xc4d2e
movl $0x1, %edi
callq 0x67c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x32(%rbp), %rdi
callq 0x64bf0
jmp 0xc54d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x61(%rbp), %rdi
callq 0x14e70
jmp 0xc54cc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0xc54c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0xc54b7
leaq -0xc8(%rbp), %rdi
callq 0xcd9e0
movq %rdx, -0x380(%rbp)
movq %rax, -0x378(%rbp)
jmp 0xc4daa
movq -0x380(%rbp), %rax
movq -0x378(%rbp), %rcx
movq %rcx, -0x104(%rbp)
movq %rax, -0xfc(%rbp)
movslq -0x104(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x390(%rbp)
movq %rax, -0x388(%rbp)
jmp 0xc4de6
movq -0x390(%rbp), %rax
movq -0x388(%rbp), %rcx
movq %rcx, -0x118(%rbp)
movq %rax, -0x110(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x101a0
xorb $-0x1, %al
testb $0x1, %al
jne 0xc4e19
jmp 0xc515c
movl -0x68(%rbp), %eax
incl %eax
movl %eax, -0x68(%rbp)
movslq -0x104(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x3a0(%rbp)
movq %rax, -0x398(%rbp)
jmp 0xc4e41
movq -0x3a0(%rbp), %rax
movq -0x398(%rbp), %rcx
movq %rcx, -0x128(%rbp)
movq %rax, -0x120(%rbp)
leaq -0x128(%rbp), %rdi
movl $0x1, %esi
callq 0x10040
leaq -0x100(%rbp), %rax
movq %rax, -0x3b0(%rbp)
movslq -0x104(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0xcd720
movq %rax, -0x3a8(%rbp)
jmp 0xc4e95
movq -0x3a8(%rbp), %rax
movq -0x3b0(%rbp), %rcx
movl 0x8(%rcx), %edx
movl %edx, 0x8(%rax)
movq (%rcx), %rcx
movq %rcx, (%rax)
leaq -0x100(%rbp), %rdi
movl -0xec(%rbp), %eax
movl %eax, -0x130(%rbp)
movq -0xf4(%rbp), %rax
movq %rax, -0x138(%rbp)
movl -0x130(%rbp), %eax
movl %eax, -0x140(%rbp)
movq -0x138(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x148(%rbp), %rsi
movl -0x140(%rbp), %edx
callq 0x94040
movb %al, -0x3b1(%rbp)
jmp 0xc4f04
movb -0x3b1(%rbp), %al
testb $0x1, %al
jne 0xc4f87
jmp 0xc4f10
movl -0xf8(%rbp), %eax
movl %eax, -0x150(%rbp)
movq -0x100(%rbp), %rax
movq %rax, -0x158(%rbp)
movl -0x150(%rbp), %eax
movl %eax, -0x160(%rbp)
movq -0x158(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x168(%rbp), %rsi
movl -0x160(%rbp), %edx
leaq 0x1ae8a8(%rip), %rdi    # 0x273800
callq 0xc8680
jmp 0xc4f5f
leaq -0xc8(%rbp), %rdi
callq 0xcda50
jmp 0xc4f6d
movq -0x100(%rbp), %rax
movq %rax, -0xf4(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, -0xec(%rbp)
movq -0x2f8(%rbp), %rdi
addq $0x60, %rdi
movslq -0x104(%rbp), %rsi
callq 0x10130
movq %rax, -0x3c0(%rbp)
jmp 0xc4fa7
movq -0x3c0(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x64400
jmp 0xc4fbc
movl $0x0, -0x1b4(%rbp)
movl -0x1b4(%rbp), %eax
movq %rax, -0x3c8(%rbp)
leaq -0x1b0(%rbp), %rdi
addq $0x20, %rdi
callq 0x2a9e0
movq %rax, %rcx
movq -0x3c8(%rbp), %rax
cmpq %rcx, %rax
jae 0xc5150
leaq -0x190(%rbp), %rdi
movl -0x1b4(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x3d0(%rbp)
jmp 0xc5013
movq -0x3d0(%rbp), %rax
movq 0x20(%rax), %rcx
movq %rcx, -0x1c0(%rbp)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movaps %xmm1, -0x1d0(%rbp)
movaps %xmm0, -0x1e0(%rbp)
movslq -0x1dc(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x3e0(%rbp)
movq %rax, -0x3d8(%rbp)
jmp 0xc505a
movq -0x3e0(%rbp), %rax
movq -0x3d8(%rbp), %rcx
movq %rcx, -0x1f0(%rbp)
movq %rax, -0x1e8(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x101a0
xorb $-0x1, %al
testb $0x1, %al
jne 0xc508d
jmp 0xc513a
leaq -0x1c8(%rbp), %rsi
leaq -0xf4(%rbp), %rdi
callq 0x94150
movl %edx, -0x3ec(%rbp)
movq %rax, -0x3e8(%rbp)
jmp 0xc50af
movl -0x3ec(%rbp), %eax
movq -0x3e8(%rbp), %rcx
movq %rcx, -0x210(%rbp)
movl %eax, -0x208(%rbp)
movl -0x208(%rbp), %eax
movl %eax, -0x1f8(%rbp)
movq -0x210(%rbp), %rax
movq %rax, -0x200(%rbp)
leaq -0x1dc(%rbp), %rsi
leaq -0x220(%rbp), %rdi
leaq -0x200(%rbp), %rdx
callq 0xcd3f0
jmp 0xc50ff
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0xcd930
jmp 0xc511b
jmp 0xc513a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x100e0
jmp 0xc54b7
jmp 0xc513c
movl -0x1b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b4(%rbp)
jmp 0xc4fc6
leaq -0x1b0(%rbp), %rdi
callq 0x100e0
jmp 0xc4ba9
leaq -0x251(%rbp), %rdi
movq %rdi, -0x3f8(%rbp)
callq 0xcdaa0
movq -0x3f8(%rbp), %rdx
leaq 0x1ae3ae(%rip), %rsi    # 0x273530
leaq -0x250(%rbp), %rdi
callq 0xcdac0
jmp 0xc5190
leaq -0x251(%rbp), %rdi
callq 0xcdb40
movl $0x0, -0x258(%rbp)
movq -0x2f8(%rbp), %rdi
movl -0x258(%rbp), %eax
movq %rax, -0x400(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, %rcx
movq -0x400(%rbp), %rax
cmpq %rcx, %rax
jae 0xc53b6
movl -0x258(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xcd720
movq %rax, -0x408(%rbp)
jmp 0xc51f0
movq -0x408(%rbp), %rsi
leaq -0x250(%rbp), %rdi
callq 0xcdb60
movq %rax, -0x410(%rbp)
jmp 0xc520c
movq -0x410(%rbp), %rax
movq %rax, -0x260(%rbp)
leaq -0x250(%rbp), %rdi
callq 0xcdbc0
movq %rax, -0x268(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0xcdb90
testb $0x1, %al
jne 0xc5249
jmp 0xc5371
leaq -0x280(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0xd0d0
movq -0x418(%rbp), %rdi
movl -0x258(%rbp), %eax
movl %eax, -0x284(%rbp)
leaq -0x284(%rbp), %rsi
callq 0xffc0
jmp 0xc527d
movl -0x258(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0xcd720
movq %rax, -0x420(%rbp)
jmp 0xc5297
movq -0x420(%rbp), %rsi
leaq -0x2b0(%rbp), %rdi
leaq -0x280(%rbp), %rdx
callq 0xcdc30
jmp 0xc52b3
leaq -0x250(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0xcdbf0
movb %dl, -0x429(%rbp)
movq %rax, -0x428(%rbp)
jmp 0xc52d5
movb -0x429(%rbp), %al
movq -0x428(%rbp), %rcx
movq %rcx, -0x2c0(%rbp)
movb %al, -0x2b8(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0xcdc70
leaq -0x280(%rbp), %rdi
callq 0xec80
jmp 0xc53a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x251(%rbp), %rdi
callq 0xcdb40
jmp 0xc54b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0xc54ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0xc5360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0xcdc70
leaq -0x280(%rbp), %rdi
callq 0xec80
jmp 0xc54ab
leaq -0x260(%rbp), %rdi
callq 0xcdc90
movq %rax, %rdi
addq $0x10, %rdi
movl -0x258(%rbp), %eax
movl %eax, -0x2c4(%rbp)
leaq -0x2c4(%rbp), %rsi
callq 0xffc0
jmp 0xc539e
jmp 0xc53a0
jmp 0xc53a2
movl -0x258(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x258(%rbp)
jmp 0xc51a6
leaq -0x250(%rbp), %rdi
callq 0xcdcb0
movq %rax, -0x2d0(%rbp)
leaq -0x250(%rbp), %rdi
callq 0xcdbc0
movq %rax, -0x2d8(%rbp)
leaq -0x2d0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0xcdce0
testb $0x1, %al
jne 0xc53f8
jmp 0xc5478
movq -0x2f8(%rbp), %rax
addq $0x90, %rax
movq %rax, -0x438(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0xcdc90
movq -0x438(%rbp), %rdi
movq %rax, %rsi
callq 0xcdd10
jmp 0xc5429
movq -0x2f8(%rbp), %rax
addq $0xa8, %rax
movq %rax, -0x440(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0xcdc90
movq -0x440(%rbp), %rdi
movq %rax, %rsi
addq $0x10, %rsi
callq 0x107f0
jmp 0xc545e
leaq -0x2d0(%rbp), %rdi
xorl %esi, %esi
callq 0xcdd80
movq %rax, -0x2e0(%rbp)
jmp 0xc53c9
leaq -0x250(%rbp), %rdi
callq 0xcddc0
leaq -0xc8(%rbp), %rdi
callq 0xcdde0
leaq -0x60(%rbp), %rdi
callq 0x14c80
leaq -0x30(%rbp), %rdi
callq 0xf9b0
addq $0x440, %rsp            # imm = 0x440
popq %rbp
retq
leaq -0x250(%rbp), %rdi
callq 0xcddc0
leaq -0xc8(%rbp), %rdi
callq 0xcdde0
leaq -0x60(%rbp), %rdi
callq 0x14c80
leaq -0x30(%rbp), %rdi
callq 0xf9b0
movq -0x40(%rbp), %rdi
callq 0x58f0
nop