diff --git a/athenasub/src/athenastring.cpp b/athenasub/src/athenastring.cpp
index dff420fba9bd5488c09b895248f7a41d48071fb1..54261fb0af839a05142d7a688faa484f316183de 100644
--- a/athenasub/src/athenastring.cpp
+++ b/athenasub/src/athenastring.cpp
@@ -455,13 +455,23 @@ int String::ToInteger() const
 {
 	size_t len = Length();
 	int value = 0;
+	int mult = 1;
 	int chr;
+	bool firstChar = true;
 	const char *data = c_str();
 	for (size_t i=0;i<len;i++) {
+		if (data[i] == ' ') continue;
 		chr = (int)(data[i])-(int)'0';
 		if (chr >= 0 && chr <= 9) value = 10*value+chr;
+		else if (firstChar && data[i] == '-') mult = -1;
+		else if (firstChar && data[i] == '+') {
+			firstChar = false;
+			continue;
+		}
+		else THROW_ATHENA_EXCEPTION(Exception::Out_Of_Range);
+		firstChar = false;
 	}
-	return value;
+	return value * mult;
 }
 
 
diff --git a/athenasub/src/athenatime.cpp b/athenasub/src/athenatime.cpp
index 5b66456e79544001c03de6444604d6b6ef402bf3..52b8f5732aac6516620aea415a0b5e0b11ac1715 100644
--- a/athenasub/src/athenatime.cpp
+++ b/athenasub/src/athenatime.cpp
@@ -80,8 +80,7 @@ int Time::GetMS() const
 String Time::GetString(int ms_precision,int h_precision) const
 {
 	// Enforce sanity
-	ms_precision = Mid(0,ms_precision,3);
-	h_precision = Max(0,h_precision);
+	if (ms_precision < 0 || ms_precision > 3 || h_precision < 0) THROW_ATHENA_EXCEPTION(Exception::Out_Of_Range);
 
 	// Generate values
 	int _ms = GetMS();
@@ -215,3 +214,41 @@ void Time::ParseString(const String &data)
 	// Set
 	SetMS((int)accum);
 }
+
+
+//////////////////
+// Get components
+int Time::GetHoursComponent() const
+{
+	return ms / 3600000;
+}
+
+int Time::GetMinutesComponent() const
+{
+	int _ms = ms;
+	int h = _ms / 3600000;
+	_ms -= h*3600000;
+	return _ms / 60000;
+}
+
+int Time::GetSecondsComponent() const
+{
+	int _ms = ms;
+	int h = _ms / 3600000;
+	_ms -= h*3600000;
+	int min = _ms / 60000;
+	_ms -= min*60000;
+	return _ms / 1000;
+}
+
+int Time::GetMillisecondsComponent() const
+{
+	int _ms = ms;
+	int h = _ms / 3600000;
+	_ms -= h*3600000;
+	int min = _ms / 60000;
+	_ms -= min*60000;
+	int s = _ms / 1000;
+	_ms -= s*1000;
+	return _ms;
+}
\ No newline at end of file
diff --git a/unit_test/src/athenasub/test_string.cpp b/unit_test/src/athenasub/test_string.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c5a4617887bada7eef9eb8cedc598860e9f90080
--- /dev/null
+++ b/unit_test/src/athenasub/test_string.cpp
@@ -0,0 +1,123 @@
+// Copyright (c) 2008, Rodrigo Braz Monteiro
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   * Redistributions of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//   * Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//   * Neither the name of the Aegisub Group nor the names of its contributors
+//     may be used to endorse or promote products derived from this software
+//     without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// -----------------------------------------------------------------------------
+//
+// AEGISUB
+//
+// Website: http://aegisub.cellosoft.com
+// Contact: mailto:zeratul@cellosoft.com
+//
+
+#include "../suites.h"
+#if ATHENASUB_TEST == 1
+
+#include <iostream>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "../../../athenasub/include/athenasub/athenasub.h"
+using namespace Athenasub;
+
+
+class AthenasubStringTest : public CppUnit::TestFixture {
+	CPPUNIT_TEST_SUITE(AthenasubStringTest);
+	CPPUNIT_TEST(testComparison);
+	CPPUNIT_TEST(testConcatenation);
+	CPPUNIT_TEST(testConversion);
+	CPPUNIT_TEST_SUITE_END();
+
+private:
+
+public:
+	void setUp()
+	{
+	}
+
+	void tearDown()
+	{
+	}
+
+	void testComparison()
+	{
+		String a;
+		String b = "";
+		String c = "Hello world!";
+		String d = "ABC";
+		String e = "abc";
+
+		CPPUNIT_ASSERT(a == "");
+		CPPUNIT_ASSERT((a == "lol") == false);
+		CPPUNIT_ASSERT(a == a);
+		CPPUNIT_ASSERT(a >= a);
+		CPPUNIT_ASSERT(a <= a);
+		CPPUNIT_ASSERT(a == b);
+		CPPUNIT_ASSERT(a != c);
+		CPPUNIT_ASSERT(d != e);
+		CPPUNIT_ASSERT(d < e);
+		CPPUNIT_ASSERT((e < d) == false);
+		CPPUNIT_ASSERT(d < c);
+		CPPUNIT_ASSERT((c < d) == false);
+	}
+
+	void testConcatenation()
+	{
+		String a;
+		CPPUNIT_ASSERT(a == "");
+		a += "Hello";
+		CPPUNIT_ASSERT(a == "Hello");
+		a += " world!";
+		CPPUNIT_ASSERT(a == "Hello world!");
+		a += 5;
+		CPPUNIT_ASSERT(a == "Hello world!5");
+		a = "";
+		a += 10.32f;
+		CPPUNIT_ASSERT(a == "10.32");
+		a = "";
+		a += 10.32;
+		CPPUNIT_ASSERT(a == "10.32");
+		a = "Hello ";
+		String b("world!");
+		CPPUNIT_ASSERT(a+b == "Hello world!");
+		a += b;
+		CPPUNIT_ASSERT(a == "Hello world!");
+	}
+
+	void testConversion()
+	{
+		CPPUNIT_ASSERT(String("312").ToInteger() == 312);
+		CPPUNIT_ASSERT(String("+312").ToInteger() == 312);
+		CPPUNIT_ASSERT(String("-312").ToInteger() == -312);
+		CPPUNIT_ASSERT(String("  31 2 ").ToInteger() == 312);
+		CPPUNIT_ASSERT_THROW(String("312a").ToInteger(),Athenasub::Exception);
+		CPPUNIT_ASSERT_THROW(String("3-12").ToInteger(),Athenasub::Exception);
+		CPPUNIT_ASSERT_THROW(String("3+12").ToInteger(),Athenasub::Exception);
+	}
+};
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AthenasubStringTest,AegisubSuites::athenasub());
+
+#endif
diff --git a/unit_test/src/athenasub/test_time.cpp b/unit_test/src/athenasub/test_time.cpp
index e2991537f36b9ea1ac2527f7e2ef70e35ff902e2..5490692971ff28471084d33f70141ea5b704689d 100644
--- a/unit_test/src/athenasub/test_time.cpp
+++ b/unit_test/src/athenasub/test_time.cpp
@@ -51,6 +51,7 @@ class AthenasubTimeTest : public CppUnit::TestFixture {
 	CPPUNIT_TEST(testSetGet);
 	CPPUNIT_TEST(testParse);
 	CPPUNIT_TEST(testToString);
+	CPPUNIT_TEST(testComponents);
 	CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -79,15 +80,17 @@ public:
 		CPPUNIT_ASSERT(a != c);
 		CPPUNIT_ASSERT(b != c);
 		CPPUNIT_ASSERT(a < c);
+		CPPUNIT_ASSERT((c < a) == false);
 		CPPUNIT_ASSERT(a <= c);
 		CPPUNIT_ASSERT(c > b);
+		CPPUNIT_ASSERT((b > c) == false);
 		CPPUNIT_ASSERT(c >= b);
 	}
 
 	void testBounds()
 	{
 		Time a(-500);
-		CPPUNIT_ASSERT(a.GetMS() >= 0);
+		CPPUNIT_ASSERT(a.GetMS() == 0);
 	}
 
 	void testSetGet()
@@ -106,6 +109,7 @@ public:
 		CPPUNIT_ASSERT(a + 300 == Time(800));
 		CPPUNIT_ASSERT(a - 300 == Time(200));
 		CPPUNIT_ASSERT(a - 600 == Time(0));
+		CPPUNIT_ASSERT(a + 500 - 500 == a);
 	}
 
 	void testParse()
@@ -149,6 +153,18 @@ public:
 		CPPUNIT_ASSERT(b.GetString(2,1) == "9:59:59.99");
 		CPPUNIT_ASSERT(c.GetString(3,2) == "99:59:59.999");
 		CPPUNIT_ASSERT(c.GetString(3,3) == "111:23:45.678");
+		CPPUNIT_ASSERT_THROW(a.GetString(-1),Athenasub::Exception);
+		CPPUNIT_ASSERT_THROW(a.GetString(4),Athenasub::Exception);
+		CPPUNIT_ASSERT_THROW(a.GetString(3,-1),Athenasub::Exception);
+	}
+
+	void testComponents()
+	{
+		Time a(1,23,45,678);
+		CPPUNIT_ASSERT(a.GetHoursComponent() == 1);
+		CPPUNIT_ASSERT(a.GetMinutesComponent() == 23);
+		CPPUNIT_ASSERT(a.GetSecondsComponent() == 45);
+		CPPUNIT_ASSERT(a.GetMillisecondsComponent() == 678);
 	}
 };
 
diff --git a/unit_test/unit_test.vcproj b/unit_test/unit_test.vcproj
index a66b6df091ed52d496694c9e4a131878acbff30f..d92b9db473cb9944882fd76e78bdfe11efbcb28a 100644
--- a/unit_test/unit_test.vcproj
+++ b/unit_test/unit_test.vcproj
@@ -180,6 +180,10 @@
 		<Filter
 			Name="Athenasub"
 			>
+			<File
+				RelativePath=".\src\athenasub\test_string.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\src\athenasub\test_time.cpp"
 				>