// File: rilutham[P]gotojakarta/./stlastar.h
// Function: AStarSearch<PathSearchNode>::SearchStep()
unsigned int SearchStep()
	{
		// Firstly break if the user has not initialised the search
		assert( (m_State > SEARCH_STATE_NOT_INITIALISED) &&
				(m_State < SEARCH_STATE_INVALID) );

		// Next I want it to be safe to do a searchstep once the search has succeeded...
		if( (m_State == SEARCH_STATE_SUCCEEDED) ||
			(m_State == SEARCH_STATE_FAILED) 
		  )
		{
			return m_State; 
		}

		// Failure is defined as emptying the open list as there is nothing left to 
		// search...
		// New: Allow user abort
		if( m_OpenList.empty() || m_CancelRequest )
		{
			FreeAllNodes();
			m_State = SEARCH_STATE_FAILED;
			return m_State;
		}
		
		// Incremement step count
		m_Steps ++;

		// Pop the best node (the one with the lowest f) 
		Node *n = m_OpenList.front(); // get pointer to the node
		pop_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
		m_OpenList.pop_back();

		// Check for the goal, once we pop that we're done
		if( n->m_UserState.IsGoal( m_Goal->m_UserState ) )
		{
			// The user is going to use the Goal Node he passed in 
			// so copy the parent pointer of n 
			m_Goal->parent = n->parent;
			m_Goal->g = n->g;

			// A special case is that the goal was passed in as the start state
			// so handle that here
			if( false == n->m_UserState.IsSameState( m_Start->m_UserState ) )
			{
				FreeNode( n );

				// set the child pointers in each node (except Goal which has no child)
				Node *nodeChild = m_Goal;
				Node *nodeParent = m_Goal->parent;

				do 
				{
					nodeParent->child = nodeChild;

					nodeChild = nodeParent;
					nodeParent = nodeParent->parent;
				
				} 
				while( nodeChild != m_Start ); // Start is always the first node by definition

			}

			// delete nodes that aren't needed for the solution
			FreeUnusedNodes();

			m_State = SEARCH_STATE_SUCCEEDED;

			return m_State;
		}
		else // not goal
		{

			// We now need to generate the successors of this node
			// The user helps us to do this, and we keep the new nodes in
			// m_Successors ...

			m_Successors.clear(); // empty vector of successor nodes to n

			// User provides this functions and uses AddSuccessor to add each successor of
			// node 'n' to m_Successors
			bool ret = n->m_UserState.GetSuccessors( this, n->parent ? &n->parent->m_UserState : NULL ); 

			if( !ret )
			{

			    typename vector< Node * >::iterator successor;

				// free the nodes that may previously have been added 
				for( successor = m_Successors.begin(); successor != m_Successors.end(); successor ++ )
				{
					FreeNode( (*successor) );
				}

				m_Successors.clear(); // empty vector of successor nodes to n

				// free up everything else we allocated
				FreeAllNodes();

				m_State = SEARCH_STATE_OUT_OF_MEMORY;
				return m_State;
			}
			
			// Now handle each successor to the current node ...
			for( typename vector< Node * >::iterator successor = m_Successors.begin(); successor != m_Successors.end(); successor ++ )
			{

				// 	The g value for this successor ...
				float newg = n->g + n->m_UserState.GetCost( (*successor)->m_UserState );

				// Now we need to find whether the node is on the open or closed lists
				// If it is but the node that is already on them is better (lower g)
				// then we can forget about this successor

				// First linear search of open list to find node

				typename vector< Node * >::iterator openlist_result;

				for( openlist_result = m_OpenList.begin(); openlist_result != m_OpenList.end(); openlist_result ++ )
				{
					if( (*openlist_result)->m_UserState.IsSameState( (*successor)->m_UserState ) )
					{
						break;					
					}
				}

				if( openlist_result != m_OpenList.end() )
				{

					// we found this state on open

					if( (*openlist_result)->g <= newg )
					{
						FreeNode( (*successor) );

						// the one on Open is cheaper than this one
						continue;
					}
				}

				typename vector< Node * >::iterator closedlist_result;

				for( closedlist_result = m_ClosedList.begin(); closedlist_result != m_ClosedList.end(); closedlist_result ++ )
				{
					if( (*closedlist_result)->m_UserState.IsSameState( (*successor)->m_UserState ) )
					{
						break;					
					}
				}

				if( closedlist_result != m_ClosedList.end() )
				{

					// we found this state on closed

					if( (*closedlist_result)->g <= newg )
					{
						// the one on Closed is cheaper than this one
						FreeNode( (*successor) );

						continue;
					}
				}

				// This node is the best node so far with this particular state
				// so lets keep it and set up its AStar specific data ...

				(*successor)->parent = n;
				(*successor)->g = newg;
				(*successor)->h = (*successor)->m_UserState.GoalDistanceEstimate( m_Goal->m_UserState );
				(*successor)->f = (*successor)->g + (*successor)->h;

				// Remove successor from closed if it was on it

				if( closedlist_result != m_ClosedList.end() )
				{
					// remove it from Closed
					FreeNode(  (*closedlist_result) ); 
					m_ClosedList.erase( closedlist_result );

					// Fix thanks to ...
					// Greg Douglas <gregdouglasmail@gmail.com>
					// who noticed that this code path was incorrect
					// Here we have found a new state which is already CLOSED
					// anus
					
				}

				// Update old version of this node
				if( openlist_result != m_OpenList.end() )
				{	   

					FreeNode( (*openlist_result) ); 
			   		m_OpenList.erase( openlist_result );

					// re-make the heap 
					// make_heap rather than sort_heap is an essential bug fix
					// thanks to Mike Ryynanen for pointing this out and then explaining
					// it in detail. sort_heap called on an invalid heap does not work
					make_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );
			
				}

				// heap now unsorted
				m_OpenList.push_back( (*successor) );

				// sort back element into heap
				push_heap( m_OpenList.begin(), m_OpenList.end(), HeapCompare_f() );

			}

			// push n onto Closed, as we have expanded it now

			m_ClosedList.push_back( n );

		} // end else (not goal so expand)

 		return m_State; // Succeeded bool is false at this point. 

	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0x148(%rbp)
xorl %eax, %eax
cmpl $0x0, 0x48(%rcx)
movb %al, -0x139(%rbp)
jbe 0x33dc
movq -0x148(%rbp), %rax
cmpl $0x5, 0x48(%rax)
setb %al
movb %al, -0x139(%rbp)
movb -0x139(%rbp), %al
testb $0x1, %al
jne 0x33e8
jmp 0x33ea
jmp 0x3409
leaq 0x3ff2(%rip), %rdi      # 0x73e3
leaq 0x3f6f(%rip), %rsi      # 0x7367
movl $0xbc, %edx
leaq 0x402c(%rip), %rcx      # 0x7430
callq 0x20b0
movq -0x148(%rbp), %rax
cmpl $0x2, 0x48(%rax)
je 0x3423
movq -0x148(%rbp), %rax
cmpl $0x3, 0x48(%rax)
jne 0x3435
movq -0x148(%rbp), %rax
movl 0x48(%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x3c4e
movq -0x148(%rbp), %rdi
callq 0x54c0
testb $0x1, %al
jne 0x3455
movq -0x148(%rbp), %rax
testb $0x1, 0x9c(%rax)
je 0x347a
movq -0x148(%rbp), %rdi
callq 0x5500
movq -0x148(%rbp), %rax
movl $0x3, 0x48(%rax)
movl 0x48(%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x3c4e
movq -0x148(%rbp), %rdi
movl 0x4c(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rdi)
callq 0x5610
movq -0x148(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x18(%rbp)
callq 0x4c70
movq -0x148(%rbp), %rdi
movq %rax, -0x20(%rbp)
callq 0x4b00
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x5640
movq -0x148(%rbp), %rdi
callq 0x56b0
movq -0x148(%rbp), %rax
movq -0x18(%rbp), %rdi
addq $0x1c, %rdi
movq 0x58(%rax), %rsi
addq $0x1c, %rsi
callq 0x25d0
testb $0x1, %al
jne 0x34f4
jmp 0x35bc
movq -0x148(%rbp), %rax
movq -0x18(%rbp), %rcx
movq (%rcx), %rdx
movq 0x58(%rax), %rcx
movq %rdx, (%rcx)
movq -0x18(%rbp), %rcx
movss 0x10(%rcx), %xmm0
movq 0x58(%rax), %rcx
movss %xmm0, 0x10(%rcx)
movq -0x18(%rbp), %rdi
addq $0x1c, %rdi
movq 0x50(%rax), %rsi
addq $0x1c, %rsi
callq 0x2390
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x3597
movq -0x148(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x56e0
movq -0x148(%rbp), %rax
movq 0x58(%rax), %rcx
movq %rcx, -0x38(%rbp)
movq 0x58(%rax), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x148(%rbp), %rcx
movq -0x38(%rbp), %rax
cmpq 0x50(%rcx), %rax
jne 0x3565
jmp 0x3597
movq -0x148(%rbp), %rdi
callq 0x5720
movq -0x148(%rbp), %rax
movl $0x2, 0x48(%rax)
movl 0x48(%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x3c4e
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x5850
movq -0x18(%rbp), %rax
addq $0x1c, %rax
movq %rax, -0x150(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
je 0x35f9
movq -0x18(%rbp), %rax
movq (%rax), %rax
addq $0x1c, %rax
movq %rax, -0x158(%rbp)
jmp 0x3604
xorl %eax, %eax
movq %rax, -0x158(%rbp)
jmp 0x3604
movq -0x148(%rbp), %rsi
movq -0x150(%rbp), %rdi
movq -0x158(%rbp), %rdx
callq 0x2600
andb $0x1, %al
movb %al, -0x41(%rbp)
testb $0x1, -0x41(%rbp)
jne 0x36d7
leaq -0x50(%rbp), %rdi
callq 0x5140
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x4c70
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x4b00
movq %rax, -0x60(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x3679
jmp 0x36a2
leaq -0x50(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq (%rax), %rsi
callq 0x56e0
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x58b0
movq %rax, -0x68(%rbp)
jmp 0x3652
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x5850
movq -0x148(%rbp), %rdi
callq 0x5500
movq -0x148(%rbp), %rax
movl $0x4, 0x48(%rax)
movl 0x48(%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x3c4e
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x4c70
movq %rax, -0x70(%rbp)
movq -0x148(%rbp), %rdi
addq $0x30, %rdi
callq 0x4b00
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x3715
jmp 0x3c2d
movq -0x18(%rbp), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x15c(%rbp)
movq -0x18(%rbp), %rax
addq $0x1c, %rax
movq %rax, -0x168(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x168(%rbp), %rdi
movq (%rax), %rsi
addq $0x1c, %rsi
callq 0x2690
movaps %xmm0, %xmm1
movss -0x15c(%rbp), %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x7c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x5140
movq -0x148(%rbp), %rdi
callq 0x4c70
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x148(%rbp), %rdi
callq 0x4b00
movq %rax, -0x98(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x37be
jmp 0x3818
leaq -0x88(%rbp), %rdi
callq 0x52e0
movq (%rax), %rax
addq $0x1c, %rax
movq %rax, -0x170(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x170(%rbp), %rdi
movq (%rax), %rsi
addq $0x1c, %rsi
callq 0x2390
testb $0x1, %al
jne 0x37fa
jmp 0x37fc
jmp 0x3818
jmp 0x37fe
leaq -0x88(%rbp), %rdi
xorl %esi, %esi
callq 0x58b0
movq %rax, -0xa0(%rbp)
jmp 0x3792
movq -0x148(%rbp), %rdi
callq 0x4b00
movq %rax, -0xa8(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x3844
jmp 0x3881
leaq -0x88(%rbp), %rdi
callq 0x52e0
movq (%rax), %rax
movss 0x10(%rax), %xmm1
movss -0x7c(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jb 0x387f
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq (%rax), %rsi
callq 0x56e0
jmp 0x3c16
jmp 0x3881
leaq -0xb0(%rbp), %rdi
callq 0x5140
movq -0x148(%rbp), %rdi
addq $0x18, %rdi
callq 0x4c70
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x148(%rbp), %rdi
addq $0x18, %rdi
callq 0x4b00
movq %rax, -0xc0(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x38e2
jmp 0x393c
leaq -0xb0(%rbp), %rdi
callq 0x52e0
movq (%rax), %rax
addq $0x1c, %rax
movq %rax, -0x178(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x178(%rbp), %rdi
movq (%rax), %rsi
addq $0x1c, %rsi
callq 0x2390
testb $0x1, %al
jne 0x391e
jmp 0x3920
jmp 0x393c
jmp 0x3922
leaq -0xb0(%rbp), %rdi
xorl %esi, %esi
callq 0x58b0
movq %rax, -0xc8(%rbp)
jmp 0x38b2
movq -0x148(%rbp), %rdi
addq $0x18, %rdi
callq 0x4b00
movq %rax, -0xd0(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x396c
jmp 0x39a9
leaq -0xb0(%rbp), %rdi
callq 0x52e0
movq (%rax), %rax
movss 0x10(%rax), %xmm1
movss -0x7c(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jb 0x39a7
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq (%rax), %rsi
callq 0x56e0
jmp 0x3c16
jmp 0x39a9
movq -0x18(%rbp), %rax
movq %rax, -0x190(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x190(%rbp), %rcx
movq (%rax), %rax
movq %rcx, (%rax)
movss -0x7c(%rbp), %xmm0
movss %xmm0, -0x188(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movss -0x188(%rbp), %xmm0
movq (%rax), %rax
movss %xmm0, 0x10(%rax)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq %rax, %rcx
movq -0x148(%rbp), %rax
movq (%rcx), %rdi
addq $0x1c, %rdi
movq 0x58(%rax), %rsi
addq $0x1c, %rsi
callq 0x23c0
movss %xmm0, -0x184(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movss -0x184(%rbp), %xmm0
movq (%rax), %rax
movss %xmm0, 0x14(%rax)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq (%rax), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x180(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movss -0x180(%rbp), %xmm0
movq (%rax), %rax
addss 0x14(%rax), %xmm0
movss %xmm0, -0x17c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x52e0
movss -0x17c(%rbp), %xmm0
movq -0x148(%rbp), %rdi
movq (%rax), %rax
movss %xmm0, 0x18(%rax)
addq $0x18, %rdi
callq 0x4b00
movq %rax, -0xd8(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x3abb
jmp 0x3b15
leaq -0xb0(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq (%rax), %rsi
callq 0x56e0
movq -0x148(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x198(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x5960
movq -0x198(%rbp), %rdi
movq -0xe0(%rbp), %rsi
callq 0x58f0
movq %rax, -0xe8(%rbp)
movq -0x148(%rbp), %rdi
callq 0x4b00
movq %rax, -0xf0(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x5870
testb $0x1, %al
jne 0x3b44
jmp 0x3bc5
leaq -0x88(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq (%rax), %rsi
callq 0x56e0
leaq -0xf8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x5960
movq -0x148(%rbp), %rdi
movq -0xf8(%rbp), %rsi
callq 0x58f0
movq -0x148(%rbp), %rdi
movq %rax, -0x100(%rbp)
callq 0x4c70
movq -0x148(%rbp), %rdi
movq %rax, -0x108(%rbp)
callq 0x4b00
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rdi
movq -0x110(%rbp), %rsi
callq 0x59a0
leaq -0x70(%rbp), %rdi
callq 0x52e0
movq -0x148(%rbp), %rdi
movq %rax, %rsi
callq 0x47d0
movq -0x148(%rbp), %rdi
callq 0x4c70
movq -0x148(%rbp), %rdi
movq %rax, -0x120(%rbp)
callq 0x4b00
movq %rax, -0x128(%rbp)
movq -0x120(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x5210
leaq -0x70(%rbp), %rdi
xorl %esi, %esi
callq 0x58b0
movq %rax, -0x138(%rbp)
jmp 0x36eb
movq -0x148(%rbp), %rdi
addq $0x18, %rdi
leaq -0x18(%rbp), %rsi
callq 0x47d0
movq -0x148(%rbp), %rax
movl 0x48(%rax), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nopw (%rax,%rax)