diff --git a/core/ajax/translations.php b/core/ajax/translations.php
index c9c642077982b0671a39ba156f932e1176248b3c..e829453dbcc59768669c786336f0e32fd828c2b1 100644
--- a/core/ajax/translations.php
+++ b/core/ajax/translations.php
@@ -27,4 +27,4 @@ $app = OC_App::cleanAppId($app);
 
 $l = OC_L10N::get( $app );
 
-OC_JSON::success(array('data' => $l->getTranslations()));
+OC_JSON::success(array('data' => $l->getTranslations(), 'plural_form' => $l->getPluralFormString()));
diff --git a/core/js/js.js b/core/js/js.js
index 03f660be62c1559e91797455b6a0ffc059aee57a..1d1711383f77aa5d62883d59e1fe8c6565b82d0b 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1,6 +1,6 @@
 /**
  * Disable console output unless DEBUG mode is enabled.
- * Add 
+ * Add
  *	 define('DEBUG', true);
  * To the end of config/config.php to enable debug mode.
  * The undefined checks fix the broken ie8 console
@@ -24,60 +24,121 @@ if (oc_debug !== true || typeof console === "undefined" || typeof console.log ==
 	}
 }
 
-/**
- * translate a string
- * @param app the id of the app for which to translate the string
- * @param text the string to translate
- * @return string
- */
-function t(app,text, vars){
-	if( !( t.cache[app] )){
-		$.ajax(OC.filePath('core','ajax','translations.php'),{
-			async:false,//todo a proper sollution for this without sync ajax calls
-			data:{'app': app},
-			type:'POST',
-			success:function(jsondata){
+function initL10N(app) {
+	if (!( t.cache[app] )) {
+		$.ajax(OC.filePath('core', 'ajax', 'translations.php'), {
+			async: false,//todo a proper solution for this without sync ajax calls
+			data: {'app': app},
+			type: 'POST',
+			success: function (jsondata) {
 				t.cache[app] = jsondata.data;
+				t.plural_form = jsondata.plural_form;
 			}
 		});
 
 		// Bad answer ...
-		if( !( t.cache[app] )){
+		if (!( t.cache[app] )) {
 			t.cache[app] = [];
 		}
 	}
-	var _build = function (text, vars) {
-		return text.replace(/{([^{}]*)}/g,
+	if (typeof t.plural_function == 'undefined') {
+		t.plural_function = function (n) {
+			var p = (n != 1) ? 1 : 0;
+			return { 'nplural' : 2, 'plural' : p };
+		};
+
+		/**
+		 * code below has been taken from jsgettext - which is LGPL licensed
+		 * https://developer.berlios.de/projects/jsgettext/
+		 * http://cvs.berlios.de/cgi-bin/viewcvs.cgi/jsgettext/jsgettext/lib/Gettext.js
+		 */
+		var pf_re = new RegExp('^(\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;a-zA-Z0-9_\(\)])+)', 'm');
+		if (pf_re.test(t.plural_form)) {
+			//ex english: "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+			//pf = "nplurals=2; plural=(n != 1);";
+			//ex russian: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 or n%100>=20) ? 1 : 2)
+			//pf = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)";
+			var pf = t.plural_form;
+			if (! /;\s*$/.test(pf)) pf = pf.concat(';');
+			/* We used to use eval, but it seems IE has issues with it.
+			 * We now use "new Function", though it carries a slightly
+			 * bigger performance hit.
+			 var code = 'function (n) { var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) }; };';
+			 Gettext._locale_data[domain].head.plural_func = eval("("+code+")");
+			 */
+			var code = 'var plural; var nplurals; '+pf+' return { "nplural" : nplurals, "plural" : (plural === true ? 1 : plural ? plural : 0) };';
+			t.plural_function = new Function("n", code);
+		} else {
+			console.log("Syntax error in language file. Plural-Forms header is invalid ["+plural_forms+"]");
+		}
+	}
+}
+/**
+ * translate a string
+ * @param app the id of the app for which to translate the string
+ * @param text the string to translate
+ * @param vars (optional) FIXME
+ * @param count (optional) number to replace %n with
+ * @return string
+ */
+function t(app, text, vars, count){
+	initL10N(app);
+	var _build = function (text, vars, count) {
+		return text.replace(/%n/g, count).replace(/{([^{}]*)}/g,
 			function (a, b) {
 				var r = vars[b];
 				return typeof r === 'string' || typeof r === 'number' ? r : a;
 			}
 		);
 	};
+	var translation = text;
 	if( typeof( t.cache[app][text] ) !== 'undefined' ){
-		if(typeof vars === 'object') {
-			return _build(t.cache[app][text], vars);
-		} else {
-			return t.cache[app][text];
+		translation = t.cache[app][text];
+	}
+
+	if(typeof vars === 'object' || count !== undefined ) {
+		return _build(translation, vars, count);
+	} else {
+		return translation;
+	}
+}
+t.cache = {};
+
+/**
+ * translate a string
+ * @param app the id of the app for which to translate the string
+ * @param text_singular the string to translate for exactly one object
+ * @param text_plural the string to translate for n objects
+ * @param count number to determine whether to use singular or plural
+ * @param vars (optional) FIXME
+ * @return string
+ */
+function n(app, text_singular, text_plural, count, vars) {
+	initL10N(app);
+	var identifier = '_' + text_singular + '__' + text_plural + '_';
+	if( typeof( t.cache[app][identifier] ) !== 'undefined' ){
+		var translation = t.cache[app][identifier];
+		if ($.isArray(translation)) {
+			var plural = t.plural_function(count);
+			return t(app, translation[plural.plural], vars, count);
 		}
 	}
+
+	if(count === 1) {
+		return t(app, text_singular, vars, count);
+	}
 	else{
-		if(typeof vars === 'object') {
-			return _build(text, vars);
-		} else {
-			return text;
-		}
+		return t(app, text_plural, vars, count);
 	}
 }
-t.cache={};
 
-/*
+/**
 * Sanitizes a HTML string
-* @param string
+* @param s string
 * @return Sanitized string
 */
 function escapeHTML(s) {
-		return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
+	return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
 }
 
 /**
@@ -773,7 +834,7 @@ OC.get=function(name) {
 	var namespaces = name.split(".");
 	var tail = namespaces.pop();
 	var context=window;
-	
+
 	for(var i = 0; i < namespaces.length; i++) {
 		context = context[namespaces[i]];
 		if(!context){
@@ -792,7 +853,7 @@ OC.set=function(name, value) {
 	var namespaces = name.split(".");
 	var tail = namespaces.pop();
 	var context=window;
-	
+
 	for(var i = 0; i < namespaces.length; i++) {
 		if(!context[namespaces[i]]){
 			context[namespaces[i]]={};
diff --git a/l10n/l10n.pl b/l10n/l10n.pl
index b07d6d686bc4a9fb77d7187f59ee10156816e07a..2790ca920152c3ecca19e015fadc4dcc5e45fd22 100644
--- a/l10n/l10n.pl
+++ b/l10n/l10n.pl
@@ -39,7 +39,7 @@ sub crawlFiles{
 	foreach my $i ( @files ){
 		next if substr( $i, 0, 1 ) eq '.';
 		next if $i eq 'l10n';
-		
+
 		if( -d $dir.'/'.$i ){
 			push( @found, crawlFiles( $dir.'/'.$i ));
 		}
@@ -64,6 +64,16 @@ sub readIgnorelist{
 	return %ignore;
 }
 
+sub getPluralInfo {
+	my( $info ) = @_;
+
+	# get string
+	$info =~ s/.*Plural-Forms: (.+)\\n.*/$1/;
+	$info =~ s/^(.*)\\n.*/$1/g;
+
+	return $info;
+}
+
 my $task = shift( @ARGV );
 my $place = '..';
 
@@ -100,11 +110,17 @@ if( $task eq 'read' ){
 
 		foreach my $file ( @totranslate ){
 			next if $ignore{$file};
-			my $keyword = ( $file =~ /\.js$/ ? 't:2' : 't');
+			my $keywords = '';
+			if( $file =~ /\.js$/ ){
+				$keywords = '--keyword=t:2 --keyword=n:2,3';
+			}
+			else{
+				$keywords = '--keyword=t --keyword=n:1,2';
+			}
 			my $language = ( $file =~ /\.js$/ ? 'Python' : 'PHP');
 			my $joinexisting = ( -e $output ? '--join-existing' : '');
 			print "    Reading $file\n";
-			`xgettext --output="$output" $joinexisting --keyword=$keyword --language=$language "$file" --from-code=UTF-8 --package-version="5.0.0" --package-name="ownCloud Core" --msgid-bugs-address="translations\@owncloud.org"`;
+			`xgettext --output="$output" $joinexisting $keywords --language=$language "$file" --from-code=UTF-8 --package-version="5.0.0" --package-name="ownCloud Core" --msgid-bugs-address="translations\@owncloud.org"`;
 		}
 		chdir( $whereami );
 	}
@@ -118,7 +134,7 @@ elsif( $task eq 'write' ){
 		print "  Processing $app\n";
 		foreach my $language ( @languages ){
 			next if $language eq 'templates';
-			
+
 			my $input = "${whereami}/$language/$app.po";
 			next unless -e $input;
 
@@ -126,18 +142,38 @@ elsif( $task eq 'write' ){
 			my $array = Locale::PO->load_file_asarray( $input );
 			# Create array
 			my @strings = ();
+			my $plurals;
+
 			foreach my $string ( @{$array} ){
-				next if $string->msgid() eq '""';
-				next if $string->msgstr() eq '""';
-				push( @strings, $string->msgid()." => ".$string->msgstr());
+				if( $string->msgid() eq '""' ){
+					# Translator information
+					$plurals = getPluralInfo( $string->msgstr());
+				}
+				elsif( defined( $string->msgstr_n() )){
+					# plural translations
+					my @variants = ();
+					my $identifier = $string->msgid()."::".$string->msgid_plural();
+					$identifier =~ s/"/_/g;
+
+					foreach my $variant ( sort { $a <=> $b} keys( %{$string->msgstr_n()} )){
+						push( @variants, $string->msgstr_n()->{$variant} );
+					}
+
+					push( @strings, "\"$identifier\" => array(".join(@variants, ",").")");
+				}
+				else{
+					# singular translations
+					next if $string->msgstr() eq '""';
+					push( @strings, $string->msgid()." => ".$string->msgstr());
+				}
 			}
 			next if $#strings == -1; # Skip empty files
 
 			# Write PHP file
 			open( OUT, ">$language.php" );
-			print OUT "<?php \$TRANSLATIONS = array(\n";
+			print OUT "<?php\n\$TRANSLATIONS = array(\n";
 			print OUT join( ",\n", @strings );
-			print OUT "\n);\n";
+			print OUT "\n);\n\$PLURAL_FORMS = \"$plurals\";\n";
 			close( OUT );
 		}
 		chdir( $whereami );
diff --git a/lib/l10n.php b/lib/l10n.php
index a28aa89c5f1efade833a1326ba7e5120f78b98a3..d2da302b6448d655702092a5edad9780ecc1b218 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -2,8 +2,10 @@
 /**
  * ownCloud
  *
+ * @author Frank Karlitschek
  * @author Jakob Sack
  * @copyright 2012 Frank Karlitschek frank@owncloud.org
+ * @copyright 2013 Jakob Sack
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -23,7 +25,7 @@
 /**
  * This class is for i18n and l10n
  */
-class OC_L10N{
+class OC_L10N {
 	/**
 	 * cached instances
 	 */
@@ -54,6 +56,16 @@ class OC_L10N{
 	 */
 	private $translations = array();
 
+	/**
+	 * Plural forms (string)
+	 */
+	private $plural_form_string = 'nplurals=2; plural=(n != 1);';
+
+	/**
+	 * Plural forms (function)
+	 */
+	private $plural_form_function = null;
+
 	/**
 	 * Localization
 	 */
@@ -66,6 +78,8 @@ class OC_L10N{
 
 	/**
 	 * get an L10N instance
+	 * @param $app string
+	 * @param $lang string|null
 	 * @return OC_L10N
 	 */
 	public static function get($app, $lang=null) {
@@ -81,8 +95,8 @@ class OC_L10N{
 
 	/**
 	 * @brief The constructor
-	 * @param $app the app requesting l10n
-	 * @param $lang default: null Language
+	 * @param $app string app requesting l10n
+	 * @param $lang string default: null Language
 	 * @returns OC_L10N-Object
 	 *
 	 * If language is not set, the constructor tries to find the right
@@ -93,6 +107,17 @@ class OC_L10N{
 		$this->lang = $lang;
 	}
 
+	public function load($transFile) {
+		$this->app = true;
+		include $transFile;
+		if(isset($TRANSLATIONS) && is_array($TRANSLATIONS)) {
+			$this->translations = $TRANSLATIONS;
+		}
+		if(isset($PLURAL_FORMS)) {
+			$this->plural_form_string = $PLURAL_FORMS;
+		}
+	}
+
 	protected function init() {
 		if ($this->app === true) {
 			return;
@@ -138,6 +163,9 @@ class OC_L10N{
 						}
 					}
 				}
+				if(isset($PLURAL_FORMS)) {
+					$this->plural_form_string = $PLURAL_FORMS;
+				}
 			}
 
 			if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php')) {
@@ -153,6 +181,65 @@ class OC_L10N{
 		}
 	}
 
+	/**
+	 * @brief Creates a function that The constructor
+	 *
+	 * If language is not set, the constructor tries to find the right
+	 * language.
+	 *
+	 * Parts of the code is copied from Habari:
+	 * https://github.com/habari/system/blob/master/classes/locale.php
+	 * @param $string string
+	 * @return string
+	 */
+	protected function createPluralFormFunction($string){
+		if(preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
+			// sanitize
+			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
+			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
+
+			$body = str_replace(
+				array( 'plural', 'n', '$n$plurals', ),
+				array( '$plural', '$n', '$nplurals', ),
+				'nplurals='. $nplurals . '; plural=' . $plural
+			);
+
+			// add parents
+			// important since PHP's ternary evaluates from left to right
+			$body .= ';';
+			$res = '';
+			$p = 0;
+			for($i = 0; $i < strlen($body); $i++) {
+				$ch = $body[$i];
+				switch ( $ch ) {
+				case '?':
+					$res .= ' ? (';
+					$p++;
+					break;
+				case ':':
+					$res .= ') : (';
+					break;
+				case ';':
+					$res .= str_repeat( ')', $p ) . ';';
+					$p = 0;
+					break;
+				default:
+					$res .= $ch;
+				}
+			}
+
+			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
+			return create_function('$n', $body);
+		}
+		else {
+			// default: one plural form for all cases but n==1 (english)
+			return create_function(
+				'$n',
+				'$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
+			);
+		}
+	}
+
 	/**
 	 * @brief Translating
 	 * @param $text String The text we need a translation for
@@ -166,6 +253,37 @@ class OC_L10N{
 		return new OC_L10N_String($this, $text, $parameters);
 	}
 
+	/**
+	 * @brief Translating
+	 * @param $text_singular String the string to translate for exactly one object
+	 * @param $text_plural String the string to translate for n objects
+	 * @param $count Integer Number of objects
+	 * @param array $parameters default:array() Parameters for sprintf
+	 * @return \OC_L10N_String Translation or the same text
+	 *
+	 * Returns the translation. If no translation is found, $text will be
+	 * returned. %n will be replaced with the number of objects.
+	 *
+	 * The correct plural is determined by the plural_forms-function
+	 * provided by the po file.
+	 *
+	 */
+	public function n($text_singular, $text_plural, $count, $parameters = array()) {
+		$this->init();
+		$identifier = "_${text_singular}__${text_plural}_";
+		if( array_key_exists($identifier, $this->translations)) {
+			return new OC_L10N_String( $this, $identifier, $parameters, $count );
+		}
+		else{
+			if($count === 1) {
+				return new OC_L10N_String($this, $text_singular, $parameters, $count);
+			}
+			else{
+				return new OC_L10N_String($this, $text_plural, $parameters, $count);
+			}
+		}
+	}
+
 	/**
 	 * @brief Translating
 	 * @param $textArray The text array we need a translation for
@@ -200,6 +318,42 @@ class OC_L10N{
 		return $this->translations;
 	}
 
+	/**
+	 * @brief getPluralFormString
+	 * @returns string containing the gettext "Plural-Forms"-string
+	 *
+	 * Returns a string like "nplurals=2; plural=(n != 1);"
+	 */
+	public function getPluralFormString() {
+		$this->init();
+		return $this->plural_form_string;
+	}
+
+	/**
+	 * @brief getPluralFormFunction
+	 * @returns string the plural form function
+	 *
+	 * returned function accepts the argument $n
+	 */
+	public function getPluralFormFunction() {
+		$this->init();
+		if(is_null($this->plural_form_function)) {
+			$this->plural_form_function = $this->createPluralFormFunction($this->plural_form_string);
+		}
+		return $this->plural_form_function;
+	}
+
+	/**
+	 * @brief get localizations
+	 * @returns Fetch all localizations
+	 *
+	 * Returns an associative array with all localizations
+	 */
+	public function getLocalizations() {
+		$this->init();
+		return $this->localizations;
+	}
+
 	/**
 	 * @brief Localization
 	 * @param $type Type of localization
@@ -230,8 +384,12 @@ class OC_L10N{
 			case 'date':
 			case 'datetime':
 			case 'time':
-				if($data instanceof DateTime) return $data->format($this->localizations[$type]);
-				elseif(is_string($data)) $data = strtotime($data);
+				if($data instanceof DateTime) {
+					return $data->format($this->localizations[$type]);
+				}
+				elseif(is_string($data)) {
+					$data = strtotime($data);
+				}
 				$locales = array(self::findLanguage());
 				if (strlen($locales[0]) == 2) {
 					$locales[] = $locales[0].'_'.strtoupper($locales[0]);
diff --git a/lib/l10n/string.php b/lib/l10n/string.php
index 8eef10071e6451010dfb385f889bcfc1cb5536af..88c85b32e70f8551093e4d342d0f362e098000dd 100644
--- a/lib/l10n/string.php
+++ b/lib/l10n/string.php
@@ -7,19 +7,50 @@
  */
 
 class OC_L10N_String{
+	/**
+	 * @var OC_L10N
+	 */
 	protected $l10n;
-	public function __construct($l10n, $text, $parameters) {
+
+	/**
+	 * @var string
+	 */
+	protected $text;
+
+	/**
+	 * @var array
+	 */
+	protected $parameters;
+
+	/**
+	 * @var integer
+	 */
+	protected $count;
+
+	public function __construct($l10n, $text, $parameters, $count = 1) {
 		$this->l10n = $l10n;
 		$this->text = $text;
 		$this->parameters = $parameters;
-
+		$this->count = $count;
 	}
 
 	public function __toString() {
 		$translations = $this->l10n->getTranslations();
+
+		$text = $this->text;
 		if(array_key_exists($this->text, $translations)) {
-			return vsprintf($translations[$this->text], $this->parameters);
+			if(is_array($translations[$this->text])) {
+				$fn = $this->l10n->getPluralFormFunction();
+				$id = $fn($this->count);
+				$text = $translations[$this->text][$id];
+			}
+			else{
+				$text = $translations[$this->text];
+			}
 		}
-		return vsprintf($this->text, $this->parameters);
+
+		// Replace %n first (won't interfere with vsprintf)
+		$text = str_replace('%n', $this->count, $text);
+		return vsprintf($text, $this->parameters);
 	}
 }
diff --git a/tests/data/l10n/cs.php b/tests/data/l10n/cs.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c5907bc148d7c83ee3afde3d6e09293a322c60e
--- /dev/null
+++ b/tests/data/l10n/cs.php
@@ -0,0 +1,5 @@
+<?php
+$TRANSLATIONS = array(
+	"_%n window__%n windows_" => array("%n okno", "%n okna", "%n oken")
+);
+$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;";
diff --git a/tests/data/l10n/de.php b/tests/data/l10n/de.php
new file mode 100644
index 0000000000000000000000000000000000000000..858ec8af49c60834e5e1b377a8b55975ea6fa74c
--- /dev/null
+++ b/tests/data/l10n/de.php
@@ -0,0 +1,5 @@
+<?php
+$TRANSLATIONS = array(
+	"_%n file__%n files_" => array("%n Datei", "%n Dateien")
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/tests/data/l10n/ru.php b/tests/data/l10n/ru.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd46293db6cdde30cd3c704d38adb5e73499a1b6
--- /dev/null
+++ b/tests/data/l10n/ru.php
@@ -0,0 +1,5 @@
+<?php
+$TRANSLATIONS = array(
+	"_%n file__%n files_" => array("%n файл", "%n файла", "%n файлов")
+);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/tests/lib/l10n.php b/tests/lib/l10n.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfc5790c2e75a369c4fe26e8314ca61f4d7c86b0
--- /dev/null
+++ b/tests/lib/l10n.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Müller <thomas.mueller@tmit.eu>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_L10n extends PHPUnit_Framework_TestCase {
+
+	public function testGermanPluralTranslations() {
+		$l = new OC_L10N('test');
+		$transFile = OC::$SERVERROOT.'/tests/data/l10n/de.php';
+
+		$l->load($transFile);
+		$this->assertEquals('1 Datei', (string)$l->n('%n file', '%n files', 1));
+		$this->assertEquals('2 Dateien', (string)$l->n('%n file', '%n files', 2));
+	}
+
+	public function testRussianPluralTranslations() {
+		$l = new OC_L10N('test');
+		$transFile = OC::$SERVERROOT.'/tests/data/l10n/ru.php';
+
+		$l->load($transFile);
+		$this->assertEquals('1 файл', (string)$l->n('%n file', '%n files', 1));
+		$this->assertEquals('2 файла', (string)$l->n('%n file', '%n files', 2));
+		$this->assertEquals('6 файлов', (string)$l->n('%n file', '%n files', 6));
+		$this->assertEquals('21 файл', (string)$l->n('%n file', '%n files', 21));
+		$this->assertEquals('22 файла', (string)$l->n('%n file', '%n files', 22));
+		$this->assertEquals('26 файлов', (string)$l->n('%n file', '%n files', 26));
+
+		/*
+		  1 file	1 файл	1 папка
+		2-4 files	2-4 файла	2-4 папки
+		5-20 files	5-20 файлов	5-20 папок
+		21 files	21 файл	21 папка
+		22-24 files	22-24 файла	22-24 папки
+		25-30 files	25-30 файлов	25-30 папок
+		etc
+		100 files	100 файлов,	100 папок
+		1000 files	1000 файлов	1000 папок
+		*/
+	}
+
+	public function testCzechPluralTranslations() {
+		$l = new OC_L10N('test');
+		$transFile = OC::$SERVERROOT.'/tests/data/l10n/cs.php';
+
+		$l->load($transFile);
+		$this->assertEquals('1 okno', (string)$l->n('%n window', '%n windows', 1));
+		$this->assertEquals('2 okna', (string)$l->n('%n window', '%n windows', 2));
+		$this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5));
+	}
+
+}