diff --git a/athenasub/athenasub_2008.vcproj b/athenasub/athenasub_2008.vcproj
index 02f449babffcbb57ccb89211943b6d5917192f1d..11ef9105b5f8009470b21bac365ee4a0b53de1e2 100644
--- a/athenasub/athenasub_2008.vcproj
+++ b/athenasub/athenasub_2008.vcproj
@@ -234,6 +234,10 @@
 				RelativePath=".\src\athenatime.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\src\athenatime.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\src\colour.cpp"
 				>
@@ -254,10 +258,6 @@
 				RelativePath=".\include\aegilib\fastbuffer.h"
 				>
 			</File>
-			<File
-				RelativePath=".\include\aegilib\gorgontime.h"
-				>
-			</File>
 			<File
 				RelativePath=".\src\prec.cpp"
 				>
@@ -291,26 +291,6 @@
 				RelativePath=".\include\aegilib\serialize.h"
 				>
 			</File>
-			<File
-				RelativePath=".\src\text_file_reader.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\src\text_file_reader.h"
-				>
-			</File>
-			<File
-				RelativePath=".\src\text_file_writer.cpp"
-				>
-			</File>
-			<File
-				RelativePath=".\src\text_file_writer.h"
-				>
-			</File>
-			<File
-				RelativePath=".\src\time.cpp"
-				>
-			</File>
 			<File
 				RelativePath=".\src\tokenizer.cpp"
 				>
@@ -464,6 +444,26 @@
 				>
 			</File>
 		</Filter>
+		<Filter
+			Name="File IO"
+			>
+			<File
+				RelativePath=".\src\text_file_reader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\text_file_reader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\text_file_writer.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\text_file_writer.h"
+				>
+			</File>
+		</Filter>
 	</Files>
 	<Globals>
 	</Globals>
diff --git a/athenasub/include/athenasub/athenastring.h b/athenasub/include/athenasub/athenastring.h
index cc5d693de04f5931b151d8232bee2370bb35c1a1..abd2ebf05c5216d7cada50ba437d2444d9492329 100644
--- a/athenasub/include/athenasub/athenastring.h
+++ b/athenasub/include/athenasub/athenastring.h
@@ -116,6 +116,7 @@ namespace Athenasub {
 		// Unicode routines
 		static size_t GetUTF8Len(const wchar_t *utf16);
 		static size_t UTF16toUTF8(const wchar_t *utf16,char *utf8);
+		static size_t UTF8toUTF16(const char *utf8,wchar_t *utf16);
 
 		//////////
 
diff --git a/athenasub/src/action.cpp b/athenasub/src/action.cpp
index 13ecd9aeebedf75d6b1f885c5642504d81469982..c383ecb0ed5517be094be3b38fa7fa052e300502 100644
--- a/athenasub/src/action.cpp
+++ b/athenasub/src/action.cpp
@@ -38,6 +38,17 @@
 using namespace Athenasub;
 
 
+///////////////////////////// Base class ///////////////////////////////
+
+///////////////
+// Constructor
+CAction::CAction(Model _model)
+: model(_model)
+{
+	if (!model) THROW_ATHENA_EXCEPTION(Exception::Internal_Error);
+}
+
+
 ///////////////////////////// Insert line /////////////////////////////
 
 ///////////////
diff --git a/athenasub/src/action.h b/athenasub/src/action.h
index 0d15b30a0433ba1c6173f91abee6889eb0ae5ea6..95ce82a6d1c7380dac52b665321660ca48cdea76 100644
--- a/athenasub/src/action.h
+++ b/athenasub/src/action.h
@@ -46,7 +46,7 @@ namespace Athenasub {
 		mutable Model model;
 
 	protected:
-		CAction(Model _model) { model = model; }
+		CAction(Model model);
 
 		Model GetModel() const { return model; }
 		Section GetSection(String name) const { return model->GetSection(name); }
diff --git a/athenasub/src/athenastring.cpp b/athenasub/src/athenastring.cpp
index 54261fb0af839a05142d7a688faa484f316183de..a8ca566e93f85cc447414303483fbd143fe60536 100644
--- a/athenasub/src/athenastring.cpp
+++ b/athenasub/src/athenastring.cpp
@@ -90,6 +90,7 @@ Character* String::GetCharPointer(size_t pos)
 
 wxString String::GetWxString() const
 {
+	// TODO: optimize this to use UTF8ToUTF16()
 	return wxString(c_str(),wxConvUTF8);
 }
 
@@ -611,3 +612,9 @@ size_t String::UTF16toUTF8(const wchar_t *utf16,char *utf8)
 	return written;
 }
 
+size_t String::UTF8toUTF16(const char *utf8,wchar_t *utf16)
+{
+	(void) utf8;
+	(void) utf16;
+	THROW_ATHENA_EXCEPTION(Exception::TODO);
+}
diff --git a/athenasub/src/athenatime.cpp b/athenasub/src/athenatime.cpp
index 7d62612f2318ecd531c74e41e0d2551a95287349..b21eaf5d5786a8bda74ea8524996482c60bfd47f 100644
--- a/athenasub/src/athenatime.cpp
+++ b/athenasub/src/athenatime.cpp
@@ -42,8 +42,8 @@ using namespace Athenasub;
 ////////////////
 // Constructors
 Time::Time()
+: ms(0)
 {
-	ms = 0;
 }
 
 Time::Time(int milliseconds)
diff --git a/athenasub/src/format_manager.cpp b/athenasub/src/format_manager.cpp
index 26b75dfa32d828f2909bdebd5fc4020125226e38..9b7750203e385a17d89ac50b8002f04f6ca768d8 100644
--- a/athenasub/src/format_manager.cpp
+++ b/athenasub/src/format_manager.cpp
@@ -84,8 +84,8 @@ const Format FormatManager::GetFormatByIndex(const int index)
 {
 	try {
 		return formats.at(index);
-	}
-	catch (...) {
+	} catch (std::out_of_range &e) {
+		(void) e;
 		return Format();
 	}
 }
diff --git a/athenasub/src/text_file_reader.cpp b/athenasub/src/text_file_reader.cpp
index 353893d20ec1de447692a242122dd737c16dc547..d1af301a04a1ffd63235750dc05963cc946ea836 100644
--- a/athenasub/src/text_file_reader.cpp
+++ b/athenasub/src/text_file_reader.cpp
@@ -49,7 +49,7 @@ using namespace Athenasub;
 
 ///////////////
 // Constructor
-TextFileReader::TextFileReader(wxInputStream &stream,Athenasub::String enc,bool _trim,bool prefetch)
+TextFileReader::TextFileReader(wxInputStream &stream,String enc,bool _trim,bool prefetch)
 : file(stream)
 {
 	// Setup
diff --git a/athenasub/src/text_file_writer.cpp b/athenasub/src/text_file_writer.cpp
index bfbc3f28f16d26bd99a07a2977fef9c6f51f2e76..916155ac89e599d36c0920588f05e3f8c56bbb2d 100644
--- a/athenasub/src/text_file_writer.cpp
+++ b/athenasub/src/text_file_writer.cpp
@@ -65,21 +65,22 @@ TextFileWriter::~TextFileWriter() {
 
 /////////////////
 // Write to file
-void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
+void TextFileWriter::WriteLineToFile(String line,bool addLineBreak) {
 	// Add line break
-	wxString temp = line.GetWxString();
+	String temp = line;//line.GetWxString();
 	if (addLineBreak && Is16) temp += _T("\r\n");
 
 	// Add BOM if it's the first line and the target format is Unicode
 	if (IsFirst && IsUnicode) {
 		wchar_t bom = 0xFEFF;
-		temp = wxString(bom) + temp;
+		temp = String(bom) + temp;
 	}
 	IsFirst = false;
 
 	// 16-bit
 	if (Is16) {
-		wxWCharBuffer buf = temp.wc_str(*conv);
+		wxString temp2 = temp.GetWxString();
+		wxWCharBuffer buf = temp2.wc_str(*conv);
 		if (!buf.data()) return;
 		size_t len = wcslen(buf.data());
 		file.Write((const char*)buf.data(),(std::streamsize)len*sizeof(wchar_t));
@@ -89,10 +90,12 @@ void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
 	else {
 		if (encoding == _T("UTF-8")) {
 			// Calculate metrics
-			const wchar_t* src = temp.c_str();
-			size_t len = temp.Length() * 2 + 2;
+			const char* src = temp.c_str();
+			size_t len = temp.Length()+1;
 			if (addLineBreak) len += 2;
-			if (buffer.size()-bufferPos < len) {
+
+			// Resize buffer if it won't fit
+			if (buffer.size() < bufferPos+len) {
 				// Flush
 				file.Write(&buffer[0],(std::streamsize)bufferPos);
 				bufferPos = 0;
@@ -101,15 +104,18 @@ void TextFileWriter::WriteLineToFile(Athenasub::String line,bool addLineBreak) {
 				if (buffer.size() < len) buffer.resize(len);
 			}
 
-			// Convert to UTF-8
-			bufferPos += String::UTF16toUTF8(src,&buffer[bufferPos]);
+			// Write UTF-8
+			size_t toWrite = strlen(src);
+			memcpy(&buffer[bufferPos],src,toWrite);
+			bufferPos += toWrite;
 			if (addLineBreak) {
 				buffer[bufferPos++] = '\r';
 				buffer[bufferPos++] = '\n';
 			}
 		}
 		else {
-			wxCharBuffer buf = temp.mb_str(*conv);
+			wxString temp2 = temp.GetWxString();
+			wxCharBuffer buf = temp2.mb_str(*conv);
 			if (!buf.data()) return;
 			size_t len = strlen(buf.data());
 			file.Write(buf.data(),(std::streamsize)len);
diff --git a/unit_test/src/main.cpp b/unit_test/src/main.cpp
index 45b422d477498f8734bd63ad1d73b1ea35a1f10e..f14249d407e80b7d3b1a08793a7d2d052c3c6d8b 100644
--- a/unit_test/src/main.cpp
+++ b/unit_test/src/main.cpp
@@ -48,6 +48,9 @@
 #endif
 
 
+bool visual_studio_open_file(char const * filename, unsigned int line);
+
+
 int main()
 {
 	CppUnit::TextUi::TestRunner runner;
@@ -57,6 +60,7 @@ int main()
 #endif
 	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
 
+	visual_studio_open_file("e:\\Projects\\aegisub\\unit_test\\src\\main.cpp",63);
 	bool result = runner.run("",false);
 	return result ? 0 : 1;
 }
diff --git a/unit_test/src/vc_open_test.cpp b/unit_test/src/vc_open_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94c7169cf5c9adb3f1d51be4c963f9b96d60df88
--- /dev/null
+++ b/unit_test/src/vc_open_test.cpp
@@ -0,0 +1,60 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <atlbase.h>
+
+// import EnvDTE
+#pragma warning(disable : 4278)
+#pragma warning(disable : 4146)
+#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only amed_guids
+#pragma warning(default : 4146)
+#pragma warning(default : 4278)
+
+bool visual_studio_open_file(char const * filename, unsigned int line)
+{
+	HRESULT result;
+	CLSID clsid;
+	result = ::CLSIDFromProgID(L"VisualStudio.DTE", &clsid);
+	if (FAILED(result))
+		return false;
+
+	CComPtr<IUnknown> punk;
+	result = ::GetActiveObject(clsid, NULL, &punk);
+	if (FAILED(result))
+		return false;
+
+	CComPtr<EnvDTE::_DTE> DTE;
+	DTE = punk;
+
+	CComPtr<EnvDTE::ItemOperations> item_ops;
+	result = DTE->get_ItemOperations(&item_ops);
+	if (FAILED(result))
+		return false;
+
+	CComBSTR bstrFileName(filename);
+	CComBSTR bstrKind(EnvDTE::vsViewKindTextView);
+	CComPtr<EnvDTE::Window> window;
+	result = item_ops->OpenFile(bstrFileName, bstrKind, &window);
+	if (FAILED(result))
+		return false;
+
+	CComPtr<EnvDTE::Document> doc;
+	result = DTE->get_ActiveDocument(&doc);
+	if (FAILED(result))
+		return false;
+
+	CComPtr<IDispatch> selection_dispatch;
+	result = doc->get_Selection(&selection_dispatch);
+	if (FAILED(result))
+		return false;
+
+	CComPtr<EnvDTE::TextSelection> selection;
+	result = selection_dispatch->QueryInterface(&selection);
+	if (FAILED(result))
+		return false;
+
+	result = selection->GotoLine(line, TRUE);
+	if (FAILED(result))
+		return false;
+
+	return true;
+}
diff --git a/unit_test/unit_test.vcproj b/unit_test/unit_test.vcproj
index 00af86c6b2f847302e918d721abf103fdac9ab07..e6b124d7240c02adfafc3eb96cddca03761e16fd 100644
--- a/unit_test/unit_test.vcproj
+++ b/unit_test/unit_test.vcproj
@@ -212,6 +212,10 @@
 				RelativePath=".\src\utils.h"
 				>
 			</File>
+			<File
+				RelativePath=".\src\vc_open_test.cpp"
+				>
+			</File>
 		</Filter>
 	</Files>
 	<Globals>