Added String.at(Integer).

Change-Id: If6567abb8529f03be9207610b58963e17c0820a6
diff --git a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/services/StringServices.java b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/services/StringServices.java
index 4991cf6..764cdf3 100644
--- a/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/services/StringServices.java
+++ b/query/plugins/org.eclipse.acceleo.query/src/org/eclipse/acceleo/query/services/StringServices.java
@@ -779,8 +779,8 @@
 	)
 	// @formatter:on
 	public String substituteAll(String self, String r, String t) {
-		return Pattern.compile(nullToEmpty(r), Pattern.LITERAL).matcher(nullToEmpty(self)).replaceAll(
-				Matcher.quoteReplacement(nullToEmpty(t)));
+		return Pattern.compile(nullToEmpty(r), Pattern.LITERAL).matcher(nullToEmpty(self)).replaceAll(Matcher
+				.quoteReplacement(nullToEmpty(t)));
 	}
 
 	// @formatter:off
@@ -856,6 +856,31 @@
 		return segments;
 	}
 
+	// @formatter:off
+	@Documentation(
+		value = "Gets the character at the given index of the given String.",
+		params = {
+			@Param(name = "self", value = "The current String"),
+			@Param(name = "index", value = "The index")
+		},
+		result = "The character at the given index",
+		examples = {
+			@Example(expression = "'cat'.at(2)", result = "'a'")
+		}
+	)
+	// @formatter:on
+	public String at(String str, Integer index) {
+		final String res;
+
+		if (str == null) {
+			res = null;
+		} else {
+			return String.valueOf(str.charAt(index - 1));
+		}
+
+		return res;
+	}
+
 	/**
 	 * Gets the empty {@link String} if the given {@link String} is <code>null</code>.
 	 * 
diff --git a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/services/tests/StringServicesTest.java b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/services/tests/StringServicesTest.java
index c210549..98bf9b1 100644
--- a/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/services/tests/StringServicesTest.java
+++ b/query/tests/org.eclipse.acceleo.query.tests/src/org/eclipse/acceleo/query/services/tests/StringServicesTest.java
@@ -1545,4 +1545,19 @@
 		assertEquals("azerty", stringServices.trim("\n\t    \razerty \t\t"));
 	}
 
+	@Test
+	public void atNullNull() {
+		assertEquals(null, stringServices.at(null, null));
+	}
+
+	@Test(expected = StringIndexOutOfBoundsException.class)
+	public void atOutOfBound() {
+		assertEquals(null, stringServices.at("cat", -1));
+	}
+
+	@Test
+	public void at() {
+		assertEquals("a", stringServices.at("cat", 2));
+	}
+
 }
diff --git a/tests/org.eclipse.acceleo.aql.migration.tests.acceleo3/status/TODO b/tests/org.eclipse.acceleo.aql.migration.tests.acceleo3/status/TODO
index e0eeeed..6d2221c 100644
--- a/tests/org.eclipse.acceleo.aql.migration.tests.acceleo3/status/TODO
+++ b/tests/org.eclipse.acceleo.aql.migration.tests.acceleo3/status/TODO
@@ -28,7 +28,6 @@
 Unsupported in A4:
 ==================
 stringServices
-	 at
 	 characters
 	 lineSeparator
 	 oclAsSet
diff --git a/tests/org.eclipse.acceleo.aql.tests/resources/completion/templatePostExpressionAfterDot-expected-completion.txt b/tests/org.eclipse.acceleo.aql.tests/resources/completion/templatePostExpressionAfterDot-expected-completion.txt
index f0297e1..9cab6bf 100644
--- a/tests/org.eclipse.acceleo.aql.tests/resources/completion/templatePostExpressionAfterDot-expected-completion.txt
+++ b/tests/org.eclipse.acceleo.aql.tests/resources/completion/templatePostExpressionAfterDot-expected-completion.txt
@@ -1,4 +1,13 @@
 * Label:
+at()
+* Description:
+at(self: java.lang.String, index: java.lang.Integer) = String<br><br>Gets the character at the given index of the given String.<br><br>  @param self<br>        The current String<br>  @param index<br>        The index<br><br>  @return<br>        The character at the given index<br><br>
+* Text:
+at()
+* Type (optional):
+http://www.eclipse.org/acceleo/4.0#//Expression
+
+* Label:
 concat()
 * Description:
 concat(self: java.lang.String, b: java.lang.String) = String<br><br>Returns a string that is the result of the concatenation of the current string and the string "b".<br><br>  @param self<br>        The current String.<br>  @param b<br>        The String that will be appended at the end of the current String.<br><br>  @return<br>        The concatenated String.<br><br>