fix advising of script node being re-initialized in new context, and other fixes
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
index 57c85c5..0defe23 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
Binary files differ
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
index bf4fb5e..f6a828b 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireBPManager.cpp
@@ -418,8 +418,7 @@
 	while (iterator != m_breakpoints->end()) {
 		CrossfireBreakpoint* breakpoint = iterator->second;
 		if (breakpoint->appliesToUrl(url)) {
-			bool success = target->setBreakpoint(breakpoint);
-			// TODO it looks like the result of the above line was to be used for something
+			target->setBreakpoint(breakpoint);
 		}
 		iterator++;
 	}
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
index 1b10614..6e0db2d 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
@@ -199,7 +199,6 @@
 		std::map<IDebugApplicationNode*, PendingScriptLoad*>::iterator iterator = m_pendingScriptLoads->begin();
 		while (iterator != m_pendingScriptLoads->end()) {
 			iterator->first->Release();
-			iterator->second->detach();
 			iterator->second->Release();
 			iterator++;
 		}
@@ -1073,18 +1072,10 @@
 bool CrossfireContext::createValueForScript(IDebugApplicationNode* node, bool includeSource, bool failIfEmpty, Value** _value) {
 	*_value = NULL;
 
-	URL* url = NULL;
-	if (!getScriptUrl(node, &url)) {
-		Logger::error("CrossfireContext.createValueForScript(): unknown script");
-		delete url;
-		return false;
-	}
-
 	CComPtr<IDebugDocument> document = NULL;
 	HRESULT hr = node->GetDocument(&document);
 	if (FAILED(hr)) {
 		Logger::error("CrossfireContext.createValueForScript(): GetDocument() failed", hr);
-		delete url;
 		return false;
 	}
 
@@ -1092,7 +1083,6 @@
 	hr = document->QueryInterface(IID_IDebugDocumentText, (void**)&documentText);
 	if (FAILED(hr)) {
 		Logger::error("CrossfireContext.createValueForScript(): QI(IDebugDocumentText) failed", hr);
-		delete url;
 		return false;
 	}
 
@@ -1101,11 +1091,15 @@
 	hr = documentText->GetSize(&numLines, &numChars);
 	if (FAILED(hr)) {
 		Logger::error("CrossfireContext.createValueForScript(): GetSize() failed", hr);
-		delete url;
 		return false;
 	}
 	if (failIfEmpty && numChars == 0) {
-		delete url;
+		return false;
+	}
+
+	URL* url = NULL;
+	if (!getScriptUrl(node, &url)) {
+		Logger::error("CrossfireContext.createValueForScript(): unknown script");
 		return false;
 	}
 
@@ -1570,6 +1564,10 @@
 		delete[] string;
 	}
 
+	if (!url.isValid()) {
+		return false;
+	}
+
 	if (!m_scriptNodes) {
 		m_scriptNodes = new std::map<std::wstring, IDebugApplicationNode*>;
 	}
@@ -1633,20 +1631,38 @@
 	return true;
 }
 
-bool CrossfireContext::scriptInitialized(IDebugApplicationNode *applicationNode) {
+bool CrossfireContext::scriptInitialized(IDebugApplicationNode *applicationNode, bool isFromAnotherContext) {
+	/*
+	 * When navigating from one page to another, the first script node for the new
+	 * page is initialized while the context for the old page is still active, and
+	 * therefore becomes registered in the wrong context.  The CrossfireServer works
+	 * around this by re-initializing the script node in the new context where it
+	 * belongs.  This workaround is aided here by keeping a reference to the last
+	 * script node that has been initialized from the document tree (but not from
+	 * another context) in case it needs to be accessible to the CrossfireServer for
+	 * re-initialization in a new context.
+	 */
 	if (m_lastInitializedScriptNode) {
 		m_lastInitializedScriptNode->Release();
+		m_lastInitializedScriptNode = NULL;
 	}
-	m_lastInitializedScriptNode = applicationNode;
-	m_lastInitializedScriptNode->AddRef();
+	if (!isFromAnotherContext) {
+		m_lastInitializedScriptNode = applicationNode;
+		m_lastInitializedScriptNode->AddRef();
+	}
 
 	registerScript(applicationNode, false);
+	scriptLoaded(applicationNode, true);
 
-	if (!scriptLoaded(applicationNode)) {
-		/*
-		 * The script's content has not been loaded yet, so create a listener
-		 * object that will invoke #scriptLoaded() when this happens
-		 */
+	/*
+	* Script loading is typically not complete when a script node is initialized, and
+	* there is no way to determine whether it is complete, so create a listener that
+	* will repeatedly invoke #scriptLoaded() as loading of the script progresses.
+	*
+	* This is not done for scripts from another context that are being re-initialized
+	* here because such scripts are advised when this context's debugger is created.
+	*/
+	if (!isFromAnotherContext) {
 		CComObject<PendingScriptLoad>* pendingScriptLoad = NULL;
 		HRESULT hr = CComObject<PendingScriptLoad>::CreateInstance(&pendingScriptLoad);
 		if (FAILED(hr)) {
@@ -1664,37 +1680,32 @@
 	return true;
 }
 
-bool CrossfireContext::scriptLoaded(IDebugApplicationNode *applicationNode) {
-	CrossfireBPManager* bpManager = m_server->getBreakpointManager();
-
+void CrossfireContext::scriptLoaded(IDebugApplicationNode *applicationNode, bool sendScriptLoadEvent) {
+	/* set the script's breakpoints if possible */
 	URL* url = NULL;
 	if (!getScriptUrl(applicationNode, &url)) {
 		Logger::error("CrossfireContext.scriptLoaded(): unknown script");
-		return false;
+		return;
 	}
-
 	/*
 	 * Incoming IBreakpointTarget method invocations should always be for this
-	 * application node, so store it temporarily so that's it's easily accessible,
+	 * application node, so store it temporarily so that it's easily accessible,
 	 * rather than repeatedly looking it up for each IBreakpointTarget invocation.
 	 */
+	CrossfireBPManager* bpManager = m_server->getBreakpointManager();
 	m_currentScriptNode = applicationNode;
 	bpManager->setBreakpointsForScript(url, this);
 	m_currentScriptNode = NULL;
 	delete url;
 
+	if (!sendScriptLoadEvent) {
+		return;
+	}
+
 	Value* script = NULL;
 	if (!createValueForScript(applicationNode, false, true, &script)) {
 		/* the script's content has probably not loaded yet */
-		return false;
-	}
-
-	/* Ensure that there is not a PendingScriptLoad remaining for this node */
-	std::map<IDebugApplicationNode*, PendingScriptLoad*>::iterator iterator = m_pendingScriptLoads->find(applicationNode);
-	if (iterator != m_pendingScriptLoads->end()) {
-		iterator->first->Release();
-		iterator->second->Release();
-		m_pendingScriptLoads->erase(iterator);
+		return;
 	}
 
 	CrossfireEvent onScriptEvent;
@@ -1704,7 +1715,6 @@
 	delete script;
 	onScriptEvent.setBody(&body);
 	sendEvent(&onScriptEvent);
-	return true;
 }
 
 void CrossfireContext::sendEvent(CrossfireEvent* eventObj) {
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
index 2dda24d..5e97574 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
@@ -45,8 +45,8 @@
 	virtual wchar_t* getUrl();
 	virtual void installBreakpoints(std::vector<Value*>* breakpoints);
 	virtual bool performRequest(CrossfireRequest* request);
-	virtual bool scriptInitialized(IDebugApplicationNode *applicationNode);
-	virtual bool scriptLoaded(IDebugApplicationNode *applicationNode);
+	virtual bool scriptInitialized(IDebugApplicationNode *applicationNode, bool isFromAnotherContext);
+	virtual void scriptLoaded(IDebugApplicationNode *applicationNode, bool sendScriptLoadEvent);
 
 	/* IBreakpointTarget methods */
 	virtual bool breakpointAttributeChanged(unsigned int handle, wchar_t* name, Value* value);
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
index d2ed0f0..b56ce1e 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp
@@ -189,7 +189,7 @@
 	CrossfireContext* context = new CrossfireContext(processId, url, this);
 	m_contexts->insert(std::pair<DWORD,CrossfireContext*> (processId, context));
 	if (scriptNode) {
-		context->scriptInitialized(scriptNode);
+		context->scriptInitialized(scriptNode, true);
 		scriptNode->Release();
 	}
 	eventContextCreated(context);
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
index dfe3901..031c5af 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
@@ -88,7 +88,7 @@
 		Logger::error("IEDebugger.onAddChild(): GetName() failed", hr);
 	} else {
 		if (wcscmp(bstrUrl, ABOUT_BLANK) != 0) {
-			m_context->scriptInitialized(prddpChild);
+			m_context->scriptInitialized(prddpChild, false);
 		}
 	}
 
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
index 67d1c81..4f6dae7 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.cpp
@@ -34,9 +34,10 @@
 }
 
 STDMETHODIMP PendingScriptLoad::onInsertText(ULONG cCharacterPosition, ULONG cNumToInsert) {
-	if (m_context && m_context->scriptLoaded(m_applicationNode)) {
-		detach();
+	if (m_context) {
+		m_context->scriptLoaded(m_applicationNode, cNumToInsert != 0);
 	}
+
 	return S_OK;
 }
 
@@ -69,7 +70,13 @@
 	CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
 	hr = document->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
 	if (FAILED(hr)) {
-		Logger::error("PendingScriptLoad.attach(): QI(IConnectionPointContainer) failed", hr);
+		/*
+		 * It is expected that this will fail for nodes that represent code evaluations
+		 * (eg.- anonymous code, eval code, script blocks).
+		 */
+		if (hr != E_NOINTERFACE) {
+			Logger::error("PendingScriptLoad.attach(): QI(IConnectionPointContainer) failed", hr);
+		}
 		return false;
 	}
 
@@ -102,22 +109,21 @@
 	if (FAILED(hr)) {
 		/* The node is already destroyed, so nothing to unadvise on */
 	} else {
-		CComPtr <IConnectionPointContainer> connectionPointContainer = NULL;
+		CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
 		hr = document->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
 		if (FAILED(hr)) {
 			Logger::error("PendingScriptLoad.detach(): QI(IID_IConnectionPointContainer) failed", hr);
-			return false;
-		}
-		CComPtr <IConnectionPoint> connectionPoint = NULL;
-		hr = connectionPointContainer->FindConnectionPoint(IID_IDebugDocumentTextEvents,&connectionPoint);
-		if (FAILED(hr)) {
-			Logger::error("PendingScriptLoad.detach(): FindConnectionPoint() failed", hr);
-			return false;
-		}
-		hr = connectionPoint->Unadvise(m_cookie);
-		if (FAILED(hr)) {
-			Logger::error("PendingScriptLoad.detach(): Unadvise() failed", hr);
-			return false;
+		} else {
+			CComPtr<IConnectionPoint> connectionPoint = NULL;
+			hr = connectionPointContainer->FindConnectionPoint(IID_IDebugDocumentTextEvents,&connectionPoint);
+			if (FAILED(hr)) {
+				Logger::error("PendingScriptLoad.detach(): FindConnectionPoint() failed", hr);
+			} else {
+				hr = connectionPoint->Unadvise(m_cookie);
+				if (FAILED(hr)) {
+					Logger::error("PendingScriptLoad.detach(): Unadvise() failed", hr);
+				}
+			}
 		}
 	}
 
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
index ff368b8..a7b4071 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/PendingScriptLoad.h
@@ -68,9 +68,9 @@
 	virtual bool detach();
 
 private:
+	IDebugApplicationNode* m_applicationNode;
 	CrossfireContext* m_context;
 	DWORD m_cookie;
-	IDebugApplicationNode* m_applicationNode;
 };
 
 OBJECT_ENTRY_AUTO(__uuidof(PendingScriptLoad), PendingScriptLoad)
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
index 9e63b03..08de997 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/URL.cpp
@@ -19,14 +19,7 @@
 
 URL::URL(wchar_t* urlString) {
 	m_value = NULL;
-
-	if (urlString) {
-		std::wstring string(urlString);
-		if (!standardize(&string)) {
-			return;
-		}
-		m_value = _wcsdup(string.c_str());
-	}
+	setString(urlString);
 }
 
 URL::~URL() {