copy from https://svn.code.sf.net/p/cppcms/code/framework/trunk