diff --git a/core/AdminCache.cpp b/core/AdminCache.cpp
index 552e56c8..57ca47cb 100644
--- a/core/AdminCache.cpp
+++ b/core/AdminCache.cpp
@@ -31,12 +31,12 @@
 
 #include <string.h>
 #include <assert.h>
+#include <ITextParsers.h>
 #include "AdminCache.h"
 #include "ShareSys.h"
 #include "ForwardSys.h"
 #include "PlayerManager.h"
 #include "ConCmdManager.h"
-#include "TextParsers.h"
 #include "Logger.h"
 #include "sourcemod.h"
 #include "sm_stringutil.h"
@@ -89,10 +89,10 @@ private:
 		m_bFileNameLogged = false;
 		g_SourceMod.BuildPath(Path_SM, m_File, sizeof(m_File), "configs/admin_levels.cfg");
 
-		if ((error = g_TextParser.ParseFile_SMC(m_File, this, &line, NULL))
+		if ((error = textparsers->ParseFile_SMC(m_File, this, &line, NULL))
 			!= SMCParse_Okay)
 		{
-			const char *err_string = g_TextParser.GetSMCErrorString(error);
+			const char *err_string = textparsers->GetSMCErrorString(error);
 			if (!err_string)
 			{
 				err_string = "Unknown error";
diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp
index a5f2ace9..f0206607 100644
--- a/core/ChatTriggers.cpp
+++ b/core/ChatTriggers.cpp
@@ -29,9 +29,9 @@
  * Version: $Id$
  */
 
+#include <ITextParsers.h>
 #include "ChatTriggers.h"
 #include "sm_stringutil.h"
-#include "TextParsers.h"
 #include "ConCmdManager.h"
 
 /* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does */
@@ -228,7 +228,7 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_
 	size_t cmd_len = 0;
 	const char *inptr = args;
 	while (*inptr != '\0' 
-			&& !IsWhitespace(inptr) 
+			&& !textparsers->IsWhitespace(inptr) 
 			&& *inptr != '"'
 			&& cmd_len < sizeof(cmd_buf) - 1)
 	{
diff --git a/core/CoreConfig.cpp b/core/CoreConfig.cpp
index 499e8a0a..7bf4fddc 100644
--- a/core/CoreConfig.cpp
+++ b/core/CoreConfig.cpp
@@ -29,6 +29,7 @@
  * Version: $Id$
  */
 
+#include <ITextParsers.h>
 #include "CoreConfig.h"
 #include "sourcemod.h"
 #include "sourcemm_api.h"
@@ -36,7 +37,6 @@
 #include "sm_version.h"
 #include "sm_stringutil.h"
 #include "LibrarySys.h"
-#include "TextParsers.h"
 #include "Logger.h"
 #include "PluginSys.h"
 #include "ForwardSys.h"
@@ -115,10 +115,10 @@ void CoreConfig::Initialize()
 	g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg);
 
 	/* Parse config file */
-	if ((err=g_TextParser.ParseFile_SMC(filePath, this, NULL, NULL)) != SMCParse_Okay)
+	if ((err=textparsers->ParseFile_SMC(filePath, this, NULL, NULL)) != SMCParse_Okay)
 	{
  		/* :TODO: This won't actually log or print anything :( - So fix that somehow */
-		const char *error = g_TextParser.GetSMCErrorString(err);
+		const char *error = textparsers->GetSMCErrorString(err);
 		g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
 	}
 }
diff --git a/core/Database.cpp b/core/Database.cpp
index 2f4d02a6..a1e58631 100644
--- a/core/Database.cpp
+++ b/core/Database.cpp
@@ -34,7 +34,6 @@
 #include "ShareSys.h"
 #include "sourcemod.h"
 #include "sm_stringutil.h"
-#include "TextParsers.h"
 #include "Logger.h"
 #include "ExtensionSys.h"
 #include <stdlib.h>
@@ -84,12 +83,12 @@ void DBManager::OnSourceModLevelChange(const char *mapName)
 	 * potentially empty/corrupt list, which would be very bad.
 	 */
 	m_pConfigLock->Lock();
-	if ((err = g_TextParser.ParseFile_SMC(m_Filename, this, &line, NULL)) != SMCParse_Okay)
+	if ((err = textparsers->ParseFile_SMC(m_Filename, this, &line, NULL)) != SMCParse_Okay)
 	{
 		g_Logger.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
 		if (err != SMCParse_Custom)
 		{
-			const char *txt = g_TextParser.GetSMCErrorString(err);
+			const char *txt = textparsers->GetSMCErrorString(err);
 			g_Logger.LogError("[SM] Line %d: %s", line, txt);
 		}
 	}
diff --git a/core/GameConfigs.cpp b/core/GameConfigs.cpp
index 85a18484..7d559270 100644
--- a/core/GameConfigs.cpp
+++ b/core/GameConfigs.cpp
@@ -32,7 +32,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include "GameConfigs.h"
-#include "TextParsers.h"
 #include "sm_stringutil.h"
 #include "sourcemod.h"
 #include "sourcemm_api.h"
@@ -504,12 +503,12 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
 	sm_trie_clear(m_pProps);
 	sm_trie_clear(m_pKeys);
 
-	if ((err=g_TextParser.ParseFile_SMC(path, this, NULL, NULL))
+	if ((err=textparsers->ParseFile_SMC(path, this, NULL, NULL))
 		!= SMCParse_Okay)
 	{
 		if (error && (err != SMCParse_Custom))
 		{
-			const char *str = g_TextParser.GetSMCErrorString(err);
+			const char *str = textparsers->GetSMCErrorString(err);
 			snprintf(error, maxlength, "%s", str);
 		}
 		return false;
diff --git a/core/TextParsers.cpp b/core/TextParsers.cpp
index 1e21f6e5..021ede39 100644
--- a/core/TextParsers.cpp
+++ b/core/TextParsers.cpp
@@ -39,11 +39,12 @@
 #include "ShareSys.h"
 
 TextParsers g_TextParser;
+ITextParsers *textparsers = &g_TextParser;
 
 static int g_ini_chartable1[255] = {0};
 static int g_ws_chartable[255] = {0};
 
-bool IsWhitespace(const char *stream)
+bool TextParsers::IsWhitespace(const char *stream)
 {
 	return g_ws_chartable[(unsigned)*stream] == 1;
 }
diff --git a/core/TextParsers.h b/core/TextParsers.h
index 517d9bf4..2dfda119 100644
--- a/core/TextParsers.h
+++ b/core/TextParsers.h
@@ -37,26 +37,6 @@
 
 using namespace SourceMod;
 
-inline unsigned int _GetUTF8CharBytes(const char *stream)
-{
-	unsigned char c = *(unsigned char *)stream;
-	if (c & (1<<7))
-	{
-		if (c & (1<<5))
-		{
-			if (c & (1<<4))
-			{
-				return 4;
-			}
-			return 3;
-		}
-		return 2;
-	}
-	return 1;
-}
-
-bool IsWhitespace(const char *stream);
-
 /**
  * @param void *			IN: Stream pointer
  * @param char *			IN/OUT: Stream buffer
@@ -88,6 +68,7 @@ public:
 	unsigned int GetUTF8CharBytes(const char *stream);
 
 	const char *GetSMCErrorString(SMCParseError err);
+	bool IsWhitespace(const char *stream);
 private:
 	SMCParseError ParseString_SMC(const char *stream, 
 		ITextListener_SMC *smc,
diff --git a/core/Translator.cpp b/core/Translator.cpp
index 9e6d0095..b2ea9659 100644
--- a/core/Translator.cpp
+++ b/core/Translator.cpp
@@ -34,7 +34,6 @@
 #include <ctype.h>
 #include "Translator.h"
 #include "Logger.h"
-#include "TextParsers.h"
 #include "LibrarySys.h"
 #include "sm_stringutil.h"
 #include "sourcemod.h"
@@ -139,9 +138,9 @@ void CPhraseFile::ReparseFile()
 
 	unsigned int line=0, col=0;
 
-	if ((err=g_TextParser.ParseFile_SMC(path, this, &line, &col)) != SMCParse_Okay)
+	if ((err=textparsers->ParseFile_SMC(path, this, &line, &col)) != SMCParse_Okay)
 	{
-		const char *msg = g_TextParser.GetSMCErrorString(err);
+		const char *msg = textparsers->GetSMCErrorString(err);
 		if (!msg)
 		{
 			msg = m_ParseError.c_str();
@@ -271,7 +270,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value,
 				} else if (*value == ',') {
 					/* Do nothing */
 				} else {
-					unsigned int bytes = g_TextParser.GetUTF8CharBytes(value);
+					unsigned int bytes = textparsers->GetUTF8CharBytes(value);
 					if (bytes != 1 || !isalpha(*value))
 					{
 						ParseWarning("Invalid token '%c' in #format property on line %d.", *value, m_CurLine);
@@ -288,7 +287,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value,
 						return SMCParse_Continue;
 					}
 				} else {
-					unsigned int bytes = g_TextParser.GetUTF8CharBytes(value);
+					unsigned int bytes = textparsers->GetUTF8CharBytes(value);
 					if (bytes != 1 || !isdigit(*value))
 					{
 						ParseWarning("Token '%c' in #format property on line %d is not a digit, phrase will be ignored.",
@@ -521,7 +520,7 @@ SMCParseResult CPhraseFile::ReadSMC_KeyValue(const char *key, const char *value,
 				unsigned int bytes;
 				while (*in_ptr != '\0')
 				{
-					bytes = g_TextParser.GetUTF8CharBytes(in_ptr);
+					bytes = textparsers->GetUTF8CharBytes(in_ptr);
 					if (bytes != 1)
 					{
 						goto scrap_point;
@@ -809,9 +808,9 @@ void Translator::RebuildLanguageDatabase(const char *lang_header_file)
 	/* Start anew */
 	SMCParseError err;
 	unsigned int line=0, col=0;
-	if ((err=g_TextParser.ParseFile_SMC(lang_header_file, this, &line, &col)) != SMCParse_Okay)
+	if ((err=textparsers->ParseFile_SMC(lang_header_file, this, &line, &col)) != SMCParse_Okay)
 	{
-		const char *str_err = g_TextParser.GetSMCErrorString(err);
+		const char *str_err = textparsers->GetSMCErrorString(err);
 		if (!str_err)
 		{
 			str_err = m_CustomError.c_str();
diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj
index f1485f69..92ac6164 100644
--- a/core/msvc8/sourcemod_mm.vcproj
+++ b/core/msvc8/sourcemod_mm.vcproj
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8,00"
+	Version="8.00"
 	Name="sourcemod_mm"
 	ProjectGUID="{E39527CD-7CAB-4420-97CC-DA1B93B260BC}"
 	RootNamespace="sourcemod_mm"
diff --git a/core/smn_string.cpp b/core/smn_string.cpp
index 97ff08ee..8202deee 100644
--- a/core/smn_string.cpp
+++ b/core/smn_string.cpp
@@ -33,7 +33,7 @@
 #include <stdlib.h>
 #include "sm_globals.h"
 #include "sm_stringutil.h"
-#include "TextParsers.h"
+#include <ITextParsers.h>
 #include <ctype.h>
 
 inline const char *_strstr(const char *str, const char *substr)
@@ -294,7 +294,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params)
 
 	const char *inptr = input;
 	/* Eat up whitespace */
-	while (*inptr != '\0' && IsWhitespace(inptr))
+	while (*inptr != '\0' && textparsers->IsWhitespace(inptr))
 	{
 		inptr++;
 	}
@@ -329,7 +329,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params)
 	} else {
 		start = inptr;
 		/* Read input until we reach a space */
-		while (*inptr != '\0' && !IsWhitespace(inptr))
+		while (*inptr != '\0' && !textparsers->IsWhitespace(inptr))
 		{
 			/* Update the end point, increment the stream. */
 			end = inptr++;
@@ -356,7 +356,7 @@ static cell_t BreakString(IPluginContext *pContext, const cell_t *params)
 	}
 
 	/* Consume more of the string until we reach non-whitespace */
-	while (*inptr != '\0' && IsWhitespace(inptr))
+	while (*inptr != '\0' && textparsers->IsWhitespace(inptr))
 	{
 		inptr++;
 	}
@@ -502,7 +502,7 @@ static cell_t TrimString(IPluginContext *pContext, const cell_t *params)
 	char *end = str + chars - 1;
 
 	/* Iterate backwards through string until we reach first non-whitespace char */
-	while (end >= str && IsWhitespace(end))
+	while (end >= str && textparsers->IsWhitespace(end))
 	{
 		end--;
 	}
@@ -511,7 +511,7 @@ static cell_t TrimString(IPluginContext *pContext, const cell_t *params)
 	*(end + 1) = '\0';
 
 	/* Iterate forwards through string until first non-whitespace char is reached */
-	while (IsWhitespace(str))
+	while (textparsers->IsWhitespace(str))
 	{
 		str++;
 	}
diff --git a/core/smn_textparse.cpp b/core/smn_textparse.cpp
index fd7753de..1c37fdc1 100644
--- a/core/smn_textparse.cpp
+++ b/core/smn_textparse.cpp
@@ -30,7 +30,7 @@
  */
 
 #include "sm_globals.h"
-#include "TextParsers.h"
+#include <ITextParsers.h>
 #include "HandleSys.h"
 
 HandleType_t g_TypeSMC = 0;
@@ -280,7 +280,7 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
 	g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file);
 
 	unsigned int line = 0, col = 0;
-	SMCParseError p_err = g_TextParser.ParseFile_SMC(path, parse, &line, &col);
+	SMCParseError p_err = textparsers->ParseFile_SMC(path, parse, &line, &col);
 
 	cell_t *c_line, *c_col;
 	pContext->LocalToPhysAddr(params[3], &c_line);
@@ -294,7 +294,7 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
 
 static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params)
 {
-	const char *str = g_TextParser.GetSMCErrorString((SMCParseError)params[1]);
+	const char *str = textparsers->GetSMCErrorString((SMCParseError)params[1]);
 
 	if (!str)
 	{
diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp
index 8e0c1e83..847b6c88 100644
--- a/core/systems/PluginSys.cpp
+++ b/core/systems/PluginSys.cpp
@@ -807,10 +807,10 @@ void CPluginManager::LoadAll_FirstPass(const char *config, const char *basedir)
 	SMCParseError err;
 	unsigned int line, col;
 	m_AllPluginsLoaded = false;
-	if ((err=g_TextParser.ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay)
+	if ((err=textparsers->ParseFile_SMC(config, &m_PluginInfo, &line, &col)) != SMCParse_Okay)
 	{
 		g_Logger.LogError("[SM] Encountered fatal error parsing file \"%s\"", config);
-		const char *err_msg = g_TextParser.GetSMCErrorString(err);
+		const char *err_msg = textparsers->GetSMCErrorString(err);
 		if (err_msg)
 		{
 			g_Logger.LogError("[SM] Parse error encountered: \"%s\"", err_msg);
diff --git a/public/ITextParsers.h b/public/ITextParsers.h
index c97959a5..16ccef62 100644
--- a/public/ITextParsers.h
+++ b/public/ITextParsers.h
@@ -362,7 +362,36 @@ namespace SourceMod
 		 * @return				Number of bytes in current character.
 		 */
 		virtual unsigned int GetUTF8CharBytes(const char *stream) =0;
+
+		/**
+		 * @brief Returns whether the first multi-byte character in the given stream
+		 * is a whitespace character.
+		 *
+		 * @param stream		Pointer to multi-byte character string.
+		 * @return				True if first character is whitespace, false otherwise.
+		 */
+		virtual bool IsWhitespace(const char *stream) =0;
 	};
+
+	inline unsigned int _GetUTF8CharBytes(const char *stream)
+	{
+		unsigned char c = *(unsigned char *)stream;
+		if (c & (1<<7))
+		{
+			if (c & (1<<5))
+			{
+				if (c & (1<<4))
+				{
+					return 4;
+				}
+				return 3;
+			}
+			return 2;
+		}
+		return 1;
+	}
 }
 
+extern SourceMod::ITextParsers *textparsers;
+
 #endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_INTERFACE_H_