FMX_PROC(errcode) BE_XPathAll ( short /* funcId */, const ExprEnv& /* environment */, const DataVect& data_vect, Data& results )
{
	errcode error_result = kNoError;
	TextAutoPtr txt;
	
	try {
		int numParams = data_vect.Size();
		StringAutoPtr xml = ParameterAsUTF8String ( data_vect, 0 );
		StringAutoPtr xpath = ParameterAsUTF8String ( data_vect, 1 );
		StringAutoPtr nsList( new string);
		if (numParams > 2)
			nsList = ParameterAsUTF8String ( data_vect, 2 );
		
		
		results.SetAsText(*ApplyXPathAll (xml, xpath, nsList), data_vect.At(0).GetLocale() );
		
	} catch ( bad_alloc e ) {
		error_result = kLowMemoryError;
	} catch ( exception e ) {
		error_result = kErrorUnknown;
	}
	
	return error_result;
	
} // BE_XPathAll
FMX_PROC(errcode) BE_WriteTextToFile ( short /* funcId */, const ExprEnv& /* environment */, const DataVect& data_vect, Data& results)
{
	errcode error_result = kNoError;
		
	try {
		
		WStringAutoPtr file = ParameterAsWideString ( data_vect, 0 );
		basic_path<wstring, wpath_traits> path = *file;
		
		// should the text be appended to the file or replace any existing contents
		
		ios_base::openmode mode = ios_base::trunc;
		if ( data_vect.Size() == 3 ) {
			bool append = data_vect.AtAsBoolean ( 2 );
			if ( append ) {
				mode = ios_base::app;
			}
		}
		
		StringAutoPtr text_to_write = ParameterAsUTF8String ( data_vect, 1 );
		
		try {
			
			basic_path<wstring, wpath_traits> filesystem_path ( path );
			boost::filesystem::ofstream output_file ( filesystem_path, ios_base::out | mode );

			output_file.exceptions ( boost::filesystem::ofstream::badbit | boost::filesystem::ofstream::failbit );			
			
			output_file << *text_to_write;
			output_file.close();

		} catch ( basic_filesystem_error<wpath> e ) {
			error_result = e.code().value();
		} catch ( exception e ) {
			error_result = errno; // unable to write to the file
		}
		
		SetNumericResult ( error_result, results );
		
	} catch ( bad_alloc e ) {
		error_result = kLowMemoryError;
	} catch ( exception e ) {
		error_result = kErrorUnknown;
	}
	
	return error_result;
	
} // BE_WriteTextToFile
long ParameterAsLong ( const DataVect& parameters, const FMX_UInt32 which, const unsigned long default_value )
{
	try {
		return parameters.AtAsNumber ( which ).AsLong();
	} catch ( exception& e ) {
		return default_value;
	}	
}
bool ParameterAsBoolean ( const DataVect& parameters, const FMX_UInt32 which, const bool default_value )
{
	try {
		return parameters.AtAsBoolean ( which );
	} catch ( exception& e ) {
		return default_value;
	}
}
WStringAutoPtr ParameterAsWideString ( const DataVect& parameters, FMX_UInt32 which )
{	
	
	WStringAutoPtr result ( new wstring );
	
	try {
		
		TextAutoPtr raw_data;
		raw_data->SetText ( parameters.AtAsText(which) );
		
		FMX_Int32 text_size = raw_data->GetSize();
		FMX_UInt16 * text = new FMX_UInt16 [ text_size + 1 ];
		raw_data->GetUnicode ( text, 0, text_size );
        text[text_size] = 0x0000;

		// wchar_t is 4 bytes on OS X and 2 on Windows
		
		#if defined(FMX_MAC_TARGET)
		
			wchar_t * parameter = new wchar_t [ text_size + 1 ];
			for ( long i = 0 ; i <= text_size ; i++ ) {
				parameter[i] = (wchar_t)text[i];
			}
			delete [] text;
		
		#endif 
		
		#if defined(FMX_WIN_TARGET)
		
			wchar_t * parameter = (wchar_t*)text;
		
		#endif
		
		result->append ( parameter );
		delete [] parameter; // parameter == text on Windows
				
	} catch ( exception& e ) {
		;	// return an empty string
	}
	
	return result;
	
} // ParameterAsUnicodeString
FMX_PROC(errcode) BE_ApplyXSLTInMemory ( short /* funcId */, const ExprEnv& /* environment */, const DataVect& data_vect, Data& results)
{
	errcode error_result = kNoError;
	
	try {
		
		StringAutoPtr xml = ParameterAsUTF8String ( data_vect, 0 );
		StringAutoPtr xslt = ParameterAsUTF8String ( data_vect, 1 );
		
		results.SetAsText( *ApplyXSLTInMemory ( xml, xslt ), data_vect.At(0).GetLocale() );
		
	} catch ( bad_alloc e ) {
		error_result = kLowMemoryError;
	} catch ( exception e ) {
		error_result = kErrorUnknown;
	}
	
	return error_result;
	
} // BE_ApplyXSLTInMemory
StringAutoPtr ParameterAsUTF8String ( const DataVect& parameters, FMX_UInt32 which )
{	
	
	StringAutoPtr result ( new string );
	
	try {
		
		TextAutoPtr raw_data;
		raw_data->SetText ( parameters.AtAsText ( which ) );
		
		FMX_UInt32 text_size = (2*(raw_data->GetSize())) + 1;
		char * text = new char [ text_size ]();
		raw_data->GetBytes ( text, text_size, 0, (FMX_UInt32)Text::kSize_End, Text::kEncoding_UTF8 );
		result->assign ( text );
		delete [] text;
		
	} catch ( exception& e ) {
		;	// return an empty string
	}
	
	return result;
	
} // ParameterAsUTF8String
FMX_PROC(errcode) BE_ExtractScriptVariables ( short /* funcId */, const ExprEnv& /* environment */, const DataVect& data_vect, Data& results)
{
	errcode error_result = kNoError;
	
	try {
		
		BEWStringVector variables;
		WStringAutoPtr calculation = ParameterAsWideString ( data_vect, 0 );

		wstring search_for = L"$/\""; // variables, comments and strings (including escaped strings)
		size_t found = calculation->find_first_of ( search_for );

		while ( found != wstring::npos )
		{
			size_t end = 0;
			size_t search_from = found + 1;
									
			switch ( calculation->at ( found ) ) {
				case L'$': // variables
				{
					/*
					 find the end of the variable
						+ - * / ^ & = ≠ < > ≤ ≥ ( , ; ) [ ] " :: $ }
					 unicode escapes are required on Windows
					 */
					
					end = calculation->find_first_of ( L" ;+-=*/&^<>\t\r[]()\u2260\u2264\u2265,", search_from );
					if ( end == wstring::npos ) {
						end = calculation->size();
					}

					// add the variable to the list
					wstring wanted = calculation->substr ( found, end - found );
					variables.PushBack ( wanted );
					search_from = end + 1;
				}
				break;
					
				case L'/': // comments
					switch ( calculation->at ( search_from ) ) {
						case L'/':
							end = calculation->find ( L"\r", search_from );
							search_from = end + 1;
							break;
							
						case L'*':
							end = calculation->find ( L"*/", search_from );
							search_from = end + 2;
							break;
							
						default:
							break;
					}
					break;
					
				case L'\"': // escaped strings
					end = calculation->find ( L"\"", search_from );
					while ( (end != string::npos) && (calculation->at ( end - 1 ) == L'\\') ) {
						end = calculation->find ( L"\"", end + 1 );
					}
					search_from = end + 1;
					break;
					
//				default:
			}
			
			// this is not on an eternal quest
			if ( (end != string::npos) && (search_from < calculation->size()) ) { 
				found = calculation->find_first_of ( search_for, search_from );
			} else {
				found = string::npos;
			}
		}
		
		results.SetAsText( *(variables.AsValueList()), data_vect.At(0).GetLocale() );
		
	} catch ( bad_alloc e ) {
		error_result = kLowMemoryError;
	} catch ( exception e ) {
		error_result = kErrorUnknown;
	}
	
	return error_result;
	
} // BE_ExtractScriptVariables