void leadHQHandle(void) {
  int rsize;
  unsigned short index[32]; // <10 keypairs in the incoming json

  // only continue if new data to read
  if (!Scout.wifi.client.available()) {
    return;
  }

  // Read a block of data and look for packets
  while ((rsize = hqIncoming.readClient(Scout.wifi.client, 128))) {
    int nl;
    while((nl = hqIncoming.indexOf('\n')) >= 0) {
     // look for a packet
      if (hqVerboseOutput) {
        Serial.print(F("looking for packet in: "));
        Serial.println(hqIncoming);
      }

      // Parse JSON up to the first newline
      if (!js0n((const unsigned char*)hqIncoming.c_str(), nl, index, 32)) {
        leadIncoming(hqIncoming.c_str(), nl, index);
      } else {
        if (hqVerboseOutput) {
          Serial.println(F("JSON parse failed"));
        }
      }

      // Remove up to and including the newline
      hqIncoming.remove(0, nl + 1);
    }
  }
}
void AbstractContextI::loadBindings(const String& configuration) throw (Exception)
{
	// replace variables in the config string: eg. "mypath" : "${env/path}" => "mypath" : "c:\\windows ..."

	Anything config;
	try { config = Anything::decodeJSON(configuration, true); }
	catch (const Exception& e) { throw Exception(WITHDETAILS(L"Invalid configuration : " + e->toString() + L"\n" + configuration)); }
	StringBuffer path;
	createBindings(config, path, 1, false);

	StringBuffer buf = configuration;
	while (-1 < buf->indexOf(L"${"))
	{
		InitialContext initialcontext = InitialContext::newInstance();
		int bpos = 0;
		int epos = 0;
		while (bpos < buf->length())
		{
			bpos = buf->indexOf(L"${", bpos);
			if (-1 == bpos) break;
			epos = buf->indexOf(L"}", bpos);
			String variablename = buf->substring(bpos + 2, epos);
			StringAnything variablevalue ;
			initialcontext->lookup(L"/" + variablename, variablevalue);
			StringBuffer value = variablevalue->toString(); 
			if (-1 < value->indexOf(L"${" + variablename + L"}") )
				throw Exception(WITHDETAILS(L"Recursive reference found : ${" + variablename + L"}"));
			buf->replace(bpos, epos + 1, value->toString());
			bpos = epos + 1;
		}

		Anything config;
		try { config = Anything::decodeJSON(buf->toString(), true); }
		catch (const Exception& e) { throw Exception(WITHDETAILS(L"Invalid configuration (2nd pass) : " + e->toString() + L"\n" + buf->toString())); }
		StringBuffer path;
		createBindings(config, path, 1, true);
	}
}
void leadHQHandle(void) {
  int rsize = 0;
  int nl;
  unsigned short index[32]; // <10 keypairs in the incoming json

  if(Scout.handler.isBridged)
  {
    rsize = (int)Scout.handler.bridge.length();
    hqIncoming += Scout.handler.bridge;
    Scout.handler.bridge = "";
  } else if (WifiModule::instance.bp()) {
    if (WifiModule::instance.bp()->client.available()) {
      rsize = hqIncoming.readClient(WifiModule::instance.bp()->client, 128);
      if(rsize > 0) Scout.handler.seen = SleepHandler::uptime().seconds;
    }
  }

  // only continue if new data to process
  if(rsize <= 0) return;
  
  // Read a block of data and look for packets
  while((nl = hqIncoming.indexOf('\n')) >= 0) {
    // look for a packet
    if(nl)
    {
      if (Scout.handler.isVerbose) {
        Serial.print(F("looking for packet in: "));
        Serial.println(hqIncoming);
      }

      // Parse JSON up to the first newline
      if (!js0n((const unsigned char*)hqIncoming.c_str(), nl, index, 32)) {
        leadIncoming(hqIncoming.c_str(), nl, index);
      } else {
        if (Scout.handler.isVerbose) {
          Serial.println(F("JSON parse failed"));
        }
      }
    }else{
      if (Scout.handler.isVerbose) {
        Serial.println(F("HQ ack'd"));
      }
    }

    // Remove up to and including the newline
    hqIncoming.remove(0, nl + 1);
  }
}
String AbstractContextI::loadValueFromFile(const String& fileurl) const throw (Exception)
{
	StringBuffer buf;
	buf->append(fileurl);
	if (0 != buf->indexOf(L"file://")) throw NamingException(WITHDETAILS(L"Expected url starting wtih 'file://' but found : " + fileurl));
	
	bool mustprependworkingdirectory = L'/' != buf->charAt(7);
	
	StringBuffer filename;
	if (L':' == buf->charAt(9)) // windows filepath
	{
		filename->append(buf->substring(8));
		filename = filename->replaceAll(L"/", L"\\");
	}
	else
	{
		filename->append(buf->substring(7));
	}


	String fullpath;
	if (mustprependworkingdirectory)
	{
		Anything value;
		lookup(L"/env/jlj_context_working_directory", value);
		String workingdirectory = value;
		fullpath = workingdirectory + filename;
	}
	else
	{
		fullpath = filename->toString();
	}
	if (verboseOutput()) cout << "JNDI context : Reading from file : " << fullpath << endl;
	InputStream file = new FileInputStreamI(fullpath);
	UTF8String content;
	file->read(content, 0);
	file->close();
	return content->toString();
}
String AbstractContextI::loadValueFromURL(const String& urlstring) const throw (Exception)
{
	String result;
	StringBuffer buf;
	buf->append(urlstring);
	if (0 == buf->indexOf(L"http://"))
	{
		URL url = new URLI(urlstring);
		HttpURLConnection httpurlconnection;
		url->openConnection()->downcast(httpurlconnection);
		if (verboseOutput()) cout << "JNDI context : Get response from url : " << urlstring << endl;
		int rc = httpurlconnection->getResponseCode();
		UTF8StringBuffer cbuf;
#if defined (_WINDOWS_SOURCE)
		cbuf->append(getenv("TEMP"));
		cbuf->append("\\");
		cbuf->append(getenv("USERNAME"));
		cbuf->append(".");
#else
		cbuf->append(getenv("USER_HOME"));
		cbuf->append("/.");
#endif
		cbuf->append(urlstring->toMD5());
		cbuf->append(".properties");
		String cachefilepath = cbuf->toString()->toLowerCase();
		if (200 != rc) 
		{
			if (verboseOutput()) cout << "JNDI context : HTTP status = " << rc << endl;
			if (verboseOutput()) cout << "JNDI context : Trying to load from cached file : " << cachefilepath << endl;
			InputStream file = new FileInputStreamI(cachefilepath);
			UTF8String content;
			file->read(content, 0);
			file->close();
			result = content->toString();
		}
		else
		{
			String response = httpurlconnection->getResponseMessage();
			Writer file = new FileWriterI(cachefilepath);
			file->write(response);
			file->close();
			if (verboseOutput()) cout << "JNDI context : Caching to file : " << cachefilepath << endl;
			result = response;
		}
	}
	else if (0 == buf->indexOf(L"file://"))
	{
		result = loadValueFromFile(urlstring);
	}
	else
	{
		throw NamingException(WITHDETAILS(L"Unsupported URI format: " + urlstring));
	}
	StringBuffer b = result;
	while (-1 < b->indexOf(L"${"))
	{
		InitialContext initialcontext = InitialContext::newInstance();
		int bpos = 0;
		int epos = 0;
		while (bpos < b->length())
		{
			bpos = b->indexOf(L"${", bpos);
			if (-1 == bpos) break;
			epos = b->indexOf(L"}", bpos);
			String variablename = b->substring(bpos + 2, epos);
			StringAnything variablevalue ;
			initialcontext->lookup(L"/" + variablename, variablevalue);
			StringBuffer value = variablevalue->toString(); 
			if (-1 < value->indexOf(L"${" + variablename + L"}") )
				throw Exception(WITHDETAILS(L"Recursive reference found : ${" + variablename + L"}"));
			b->replace(bpos, epos + 1, value->toString());
			bpos = epos + 1;
		}
	}
	return b->toString();
}
Object AbstractContextI::lookupObjectFactory(const String& name,
											 bool& createdbyfactory,
											 String& redirectedname) const throw (NamingException)
{
	try
	{
		redirectedname = name;
		createdbyfactory = false;
		Object object = lookupWithSyntaxCheck(name, false);
		StringAnything referencelink;
		if (object->instanceOf(referencelink))
		{
			if (isBound(referencelink->toString()))
			{
				object = lookupURL(referencelink->toString());
				redirectedname = referencelink->toString();
			}
		}
		MapAnything objectfactory;
		if (object->instanceOf(objectfactory))
		{
			if (objectfactory->containsKey(L"class") && objectfactory->containsKey(L"library"))
			{
				bool load = true;
				if (objectfactory->containsKey(L"load")) load = objectfactory->get(L"load");
				if (load)
				{
					ClassLoader classloader;
					String clazzname = objectfactory->get(L"class");

					Anything library = objectfactory->get(L"library");
					if (Anything::ANY_STRING == library->type())
					{
						StringBuffer buf = library->toString();
						if (0 == buf->indexOf(L"http://"))
						{
							classloader = new URLClassLoaderI();
						}
						else
						{
							classloader = new ClassLoaderI();
						}
						classloader->loadLibrary(library);
					}
					else
					{
						if (Anything::ANY_LIST == library->type())
						{
							classloader = new URLClassLoaderI();
							Iterator<Anything> i = library->iterator();
							while (i->hasNext())
							{
								String library = i->next();
								classloader->loadLibrary(library);
							}
						}
					}
					object = classloader->loadClass(clazzname)->newInstance();
					const_cast<AbstractContextI*>(this)->rebind(name, object);
					createdbyfactory = true;
					const_cast<AbstractContextI*>(this)->bind(
						name + L"/" + name->toMD5(), new StringAnythingI(redirectedname));
				}
			}
		}
		else
		{
			createdbyfactory = isBound(name + L"/" + name->toMD5());
			if (createdbyfactory) redirectedname = lookup(name + L"/" + name->toMD5())->toString(); 
		}
		return object;
	}
	catch (const NamingException&)
	{
		throw;
	}
	catch (const Exception& e)
	{
		throw NamingException(WITHDETAILS(e->toString()));;
	}
}
inline bool startsWith(const String& what, const String& with)
{
	StringBuffer buffer;
	buffer->append(what);
	return 0 == buffer->indexOf(with);
}