Index: /CKLangTool/trunk/_source/includes/cklangtool.js
===================================================================
--- /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 7309)
+++ /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 7310)
@@ -243,4 +243,16 @@
 	} )();
 
+	/**
+	 * Helper function that converts strings from "array" into "pseudo object" notation.
+	 * E.g the following string:
+	 * foo[1].bar[0].baz
+	 * is changed into:
+	 * foo.1.bar.0.baz
+	 * @param key
+	 */
+	function objectify( key )
+	{
+		return key.replace(/\[/g, '.').replace(/\]/g, '');
+	}
 
 	var regexLib =
@@ -255,6 +267,9 @@
 		arrayTranslationKey :Pattern.compile( "^(.*)\\[(\\d+)\\]$" ),
 		objectName :Pattern.compile( "^\\s*((?:'|\")?)([a-z][_a-z0-9]*)\\1\\s*:\\s*(?://.*)?$", Pattern.CASE_INSENSITIVE ),
-		objectStart :Pattern.compile( "\\{" ),
-		objectEnd :Pattern.compile( "\\}" ),
+		objectStart :Pattern.compile( "\\{\\s*$" ),
+		objectEnd :Pattern.compile( "^\\s*\\}" ),
+		stringValue :Pattern.compile( "^(\\s*\\').*?(\\'\\s*)(?:\\+)?\\s*(?://.*)?$" ),
+		arrayStart :Pattern.compile( "\\[\\s*$" ),
+		arrayEnd :Pattern.compile( "^\\s*\\]" ),
 		fileOverview :Pattern.compile( " @fileOverview" ),
 		translation :Pattern.compile( "#ckeditor_translation[^#]*?#" ),
@@ -277,4 +292,9 @@
 		var objectName, matcher, line, translationKey;
 		var lines = CKLANGTOOL.io.readFileIntoArray( file );
+		var isArray = {}, arrayIndex = {};
+		var stripPrefix = function( str )
+		{
+			return str.replace( /^ckeditor_translation\./, "" );
+		}
 
 		for ( var j = 0 ; j < lines.length ; j++ )
@@ -301,4 +321,5 @@
 				{
 					objectName = matcher.group( 2 );
+					objectNameLineNumber = j;
 					continue;
 				}
@@ -307,10 +328,19 @@
 				{
 					matcher = regexLib.objectStart.matcher( line );
+					var keyWithoutIndex = key.replace( /\[\d+\]$/, '' );
 					/*
-					 * We have found an opening bracket, key -> key.objectName
+					 * We have found an opening "{" bracket, key -> key.objectName
 					 */
 					if ( matcher.find() )
 					{
-						key = key + "." + objectName;
+						if ( isArray[keyWithoutIndex] )
+						{
+							key = keyWithoutIndex + '[' + ( arrayIndex[keyWithoutIndex]++ ) + ']';
+						}
+						else
+						{
+							key = key + "." + objectName;
+						}
+
 						continue;
 					}
@@ -318,5 +348,34 @@
 					matcher = regexLib.objectEnd.matcher( line );
 					/*
-					 * We have found a closing bracket, key.objectName -> key
+					 * We have found a closing "}" bracket, key.objectName -> key
+					 */
+					if ( matcher.find() )
+					{
+						if ( !isArray[keyWithoutIndex] )
+						{
+							if ( key.indexOf( "." ) != -1 )
+								key = key.slice( 0, key.lastIndexOf( "." ) );
+						}
+
+						continue;
+					}
+
+					matcher = regexLib.arrayStart.matcher( line );
+					/*
+					 * We have found an opening "[" bracket
+					 */
+					if ( matcher.find() )
+					{
+						key = key + "." + objectName;
+
+						isArray[key] = true;
+						arrayIndex[key] = 0;
+
+						continue;
+					}
+
+					matcher = regexLib.arrayEnd.matcher( line );
+					/*
+					 * We have found a closing "]" bracket
 					 */
 					if ( matcher.find() )
@@ -324,4 +383,5 @@
 						if ( key.indexOf( "." ) != -1 )
 							key = key.slice( 0, key.lastIndexOf( "." ) );
+
 						continue;
 					}
@@ -334,7 +394,6 @@
 				if ( matcher.find() && regexLib.missing.matcher( line ).find() )
 				{
-					translationKey = key + "." + matcher.group( 3 );
-					translationKey = translationKey.replace( /^ckeditor_translation\./, "" );
-					out[ translationKey ] = true;
+					translationKey = stripPrefix( key + "." + matcher.group( 3 ) );
+					out[ objectify(translationKey) ] = true;
 				}
 
@@ -345,7 +404,23 @@
 				if ( matcher.find() && regexLib.missing.matcher( line ).find() )
 				{
-					translationKey = key + "." + matcher.group( 3 );
-					translationKey = translationKey.replace( /^ckeditor_translation\./, "" );
-					out[ translationKey ] = true;
+					translationKey = stripPrefix( key + "." + matcher.group( 3  ));
+					out[ objectify(translationKey) ] = true;
+				}
+
+				/*
+				 * The following entry is not caught by regexLib.entry pattern
+				 * and needs a special treatment.
+				 * someEntry:
+				 *            'a long string ' +
+				 *            'split into ' +
+				 *            'few lines'
+				 */
+				matcher = regexLib.stringValue.matcher( line );
+				if ( matcher.find() && regexLib.missing.matcher( line ).find() )
+				{
+					if ( objectNameLineNumber == j-1 )
+					{
+						out[ objectify(stripPrefix(key)) + "." + objectName ] = true;
+					}
 				}
 			}
@@ -393,4 +468,6 @@
 		var arrayEntryItems, arrayEntryItemsMatcher, arrayEntryLineEnd, arrayEntryLine, arrayEntryKey;
 		var lines = CKLANGTOOL.io.readFileIntoArray( file );
+		var isArray = {}, arrayIndex = {};
+		var objectNameLineNumber;
 
 		for ( var j = 0 ; j < lines.length ; j++ )
@@ -419,4 +496,5 @@
 				{
 					objectName = matcher.group( 2 );
+					objectNameLineNumber = j;
 					out.push( line );
 					continue;
@@ -426,10 +504,19 @@
 				{
 					matcher = regexLib.objectStart.matcher( line );
+					var keyWithoutIndex = key.replace( /\[\d+\]$/, '' );
 					/*
-					 * We have found an opening bracket, key -> key.objectName
+					 * We have found an opening "{" bracket, key -> key.objectName
 					 */
 					if ( matcher.find() )
 					{
-						key = key + "." + objectName;
+						if ( isArray[keyWithoutIndex] )
+						{
+							key = keyWithoutIndex + '[' + ( arrayIndex[keyWithoutIndex]++ ) + ']';
+						}
+						else
+						{
+							key = key + "." + objectName;
+						}
+
 						out.push( line );
 						continue;
@@ -438,9 +525,42 @@
 					matcher = regexLib.objectEnd.matcher( line );
 					/*
-					 * We have found a closing bracket, key.objectName -> key
+					 * We have found a closing "}" bracket, key.objectName -> key
 					 */
 					if ( matcher.find() )
 					{
-						key = key.slice( 0, key.lastIndexOf( "." ) );
+						if ( !isArray[keyWithoutIndex] )
+						{
+							if ( key.indexOf( "." ) != -1 )
+								key = key.slice( 0, key.lastIndexOf( "." ) );
+						}
+
+						out.push( line );
+						continue;
+					}
+
+					matcher = regexLib.arrayStart.matcher( line );
+					/*
+					 * We have found an opening "[" bracket
+					 */
+					if ( matcher.find() )
+					{
+						key = key + "." + objectName;
+
+						isArray[key] = true;
+						arrayIndex[key] = 0;
+
+						out.push( line );
+						continue;
+					}
+
+					matcher = regexLib.arrayEnd.matcher( line );
+					/*
+					 * We have found a closing "]" bracket
+					 */
+					if ( matcher.find() )
+					{
+						if ( key.indexOf( "." ) != -1 )
+							key = key.slice( 0, key.lastIndexOf( "." ) );
+
 						out.push( line );
 						continue;
@@ -514,4 +634,23 @@
 				}
 
+				/*
+				 * The following entry is not caught by regexLib.entry pattern
+				 * and needs a special treatment.
+				 * someEntry:
+				 *            'a long string ' +
+				 *            'split into ' +
+				 *            'few lines'
+				 */
+				matcher = regexLib.stringValue.matcher( line );
+				if ( matcher.find() )
+				{
+					if ( objectNameLineNumber == j-1 )
+					{
+						out.push( matcher.group( 1 ) + "#" + key + "." + objectName + "#"
+							+ matcher.group( 2 ) );
+					}
+					continue;
+				}
+
 				out.push( line );
 			}
@@ -572,4 +711,13 @@
 			return fileOverviewBlock;
 
+		/**
+		 * Below we have a loop where '.' is used to mark another nesting level.
+		 * Array indices also mean another nesting levels, so we change:
+		 * ckeditor_translation.legend[1].items[0].name
+		 * into
+		 * ckeditor_translation.legend.1.items.0.name
+		 * to properly handle arrays in this loop.
+		 */
+		translationKey = objectify(translationKey);
 		while ( (dotPos = translationKey.indexOf( "." )) != -1 )
 		{
@@ -582,20 +730,5 @@
 		}
 
-		/*
-		 * First make sure that the translationKey is not an array.
-		 */
-		var matcher = regexLib.arrayTranslationKey.matcher( translationKey );
-		if ( matcher.find() )
-		{
-			if ( typeof (result[ matcher.group( 1 ) ]) != "object" )
-			{
-				return false;
-			}
-			result = result[ matcher.group( 1 ) ][ matcher.group( 2 ) ];
-		}
-		else
-		{
-			result = result[ translationKey ];
-		}
+		result = result[ translationKey ];
 
 		if ( typeof (result) == "undefined" )
@@ -624,4 +757,5 @@
 		var result = CKLANGTOOL.loadLanguageFile( file );
 		var translation = result.translation;
+		var newFile = false;
 		languageCode = result.languageCode;
 
@@ -630,4 +764,5 @@
 			print( 'Destination file does not exist: ' + dst );
 			info = { missingKeys : [], fileOverviewBlock : '' };
+			newFile = true;
 		}
 		else {
@@ -651,5 +786,6 @@
 			 * common.textField[1] -> common.textField
 			 */
-			if ( replacement == false || missingKeys[ translationKey.replace( /\[\d+\]$/, "" ) ] )
+			var key = objectify(translationKey.replace( /\[\d+\]$/, "" ));
+			if ( replacement == false || missingKeys[ key ] )
 			{
 				/**
@@ -695,5 +831,10 @@
 		}
 
-		CKLANGTOOL.io.saveFile( dst, lines.join( "\r\n" ), false );
+		/**
+		 * Save file only when updating existing one, or if there was at least one translated string.
+		 * It has no sense to create a new translation file if no strings are found.
+		 */
+		if ( found > 0 || !newFile )
+			CKLANGTOOL.io.saveFile( dst, lines.join( "\r\n" ), false );
 
 		var result =
@@ -701,5 +842,6 @@
 			langFile : dst.getName(),
 			found :found,
-			missing :missing
+			missing :missing,
+			newFile : newFile
 		};
 
@@ -772,5 +914,8 @@
 				print( "Processing " + file.getAbsolutePath() );
 				result = processFile( file );
-				checkFile( file );
+				if ( result.found || !result.newFile )
+					checkFile( file );
+				else
+					continue;
 
 				languages.push( result.langFile );
Index: /CKLangTool/trunk/test/_assets/gettext/en.js
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/en.js	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/gettext/en.js	(revision 7310)
@@ -51,8 +51,12 @@
 	// Special char dialog.
 	specialChar		:
-	{
-		toolbar		: 'Insert Special Character',
-		title		: 'Select Special Character'
-	},
+	[
+		{
+			toolbar		: 'Insert Special Character'
+		},
+		{
+			title		: 'Select Special Character'
+		}
+	],
 
 	// Link dialog.
Index: /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/gettext/en.po.correct.txt	(revision 7310)
@@ -46,8 +46,8 @@
 msgstr "Some of the options have been changed. Are you sure to close the dialog?"
 
-msgid "specialChar.toolbar"
+msgid "specialChar.0.toolbar"
 msgstr "Insert Special Character"
 
-msgid "specialChar.title"
+msgid "specialChar.1.title"
 msgstr "Select Special Character"
 
Index: /CKLangTool/trunk/test/_assets/gettext/pl.js
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/pl.js	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/gettext/pl.js	(revision 7310)
@@ -45,8 +45,12 @@
 	// Special char dialog.
 	specialChar		:
-	{
-		toolbar		: 'Wstaw znak specjalny',
-		title		: 'Wybierz znak specjalny'
-	},
+	[
+		{
+			toolbar		: 'Wstaw znak specjalny'
+		},
+		{
+			title		: 'Wybierz znak specjalny'
+		}
+	],
 
 	// Link dialog.
Index: /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/gettext/pl.po.correct.txt	(revision 7310)
@@ -43,8 +43,8 @@
 msgstr ""
 
-msgid "specialChar.toolbar"
+msgid "specialChar.0.toolbar"
 msgstr "Wstaw znak specjalny"
 
-msgid "specialChar.title"
+msgid "specialChar.1.title"
 msgstr "Wybierz znak specjalny"
 
Index: /CKLangTool/trunk/test/_assets/translator/pl.js
===================================================================
--- /CKLangTool/trunk/test/_assets/translator/pl.js	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator/pl.js	(revision 7310)
@@ -57,5 +57,5 @@
 		'toolbar'		: 'Wstaw/edytuj hiperłącze',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
 		noAnchors		: '(W dokumencie nie zdefiniowano żadnych etykiet)',
-		noUrl			: 'Podaj adres URL',
+		noUrl			: 'Podaj [adres] URL',
 		noEmail			: 'Podaj adres e-mail'
 	},
Index: /CKLangTool/trunk/test/_assets/translator/pl.js.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/translator/pl.js.correct.txt	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator/pl.js.correct.txt	(revision 7310)
@@ -65,5 +65,5 @@
 		'toolbar'		: 'Wstaw/edytuj hiperłącze',		// IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
 		noAnchors		: '(W dokumencie nie zdefiniowano żadnych etykiet)',
-		noUrl			: 'Podaj adres URL',
+		noUrl			: 'Podaj [adres] URL',
 		noEmail			: 'Podaj adres e-mail'
 	},
Index: /CKLangTool/trunk/test/_assets/translator2/_translationstatus.txt.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/translator2/_translationstatus.txt.correct.txt	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator2/_translationstatus.txt.correct.txt	(revision 7310)
@@ -2,3 +2,3 @@
 For licensing, see LICENSE.html or http://ckeditor.com/license
 
-he.js      Found: 3 Missing: 1
+he.js      Found: 14 Missing: 3
Index: /CKLangTool/trunk/test/_assets/translator2/en.js
===================================================================
--- /CKLangTool/trunk/test/_assets/translator2/en.js	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator2/en.js	(revision 7310)
@@ -12,4 +12,51 @@
 		config : 'Paste this string into your config.js file',
 		predefined : 'Predefined color sets'
+	},
+
+	accessibilityHelp :
+	{
+		title : 'Accessibility Instructions',
+		legend :
+		[
+			{
+				name : 'General',
+				items :
+						[
+							{
+								name : 'Editor Toolbar',
+								legend:
+									'Press ${toolbarFocus} to navigate to the toolbar. ' +
+									'Move to the next and previous toolbar group with TAB and SHIFT-TAB. ' +
+									'Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. ' +
+									'Press SPACE or ENTER to activate the toolbar button.'
+							},
+							{
+								name : 'Editor Dialog'
+							}
+						]
+			},
+			{
+				name : 'Commands',
+				items :
+						[
+							{
+								name : ' Undo command',
+								legend :
+									'Press ${undo}'
+							},
+							{
+								name : ' Redo command',
+								legend : 
+									'Press ${redo}'
+							},
+							{
+								name : ' Bold command',
+								legend : 'Press ${bold}'
+							}
+						]
+			}
+		],
+		contents : 'Help Contents. To close this dialog press ESC.'
 	}
+
 });
Index: /CKLangTool/trunk/test/_assets/translator2/he.js
===================================================================
--- /CKLangTool/trunk/test/_assets/translator2/he.js	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator2/he.js	(revision 7310)
@@ -11,4 +11,46 @@
 		config : 'הדבק את הטקסט הבא לתוך הקובץ config.js',
 		predefined : 'קבוצות צבעים מוגדרות מראש'
+	},
+
+	accessibilityHelp :
+	{
+		title : 'הוראות נגישות',
+		legend :
+		[
+			{
+				name : 'כללי',
+				items :
+						[
+							{
+								name : 'סרגל הכלים'
+							},
+
+							{
+								name : 'דיאלוגים (חלונות תשאול)'
+							}
+						]
+			},
+			{
+				name : 'פקודות',
+				items :
+						[
+							{
+								name : ' ביטול צעד אחרון',
+								legend : 
+									'לחץ ${undo}'
+							},
+							{
+								name : ' חזרה על צעד אחרון',
+								legend :
+									'Press ${redo}' // MISSING
+							},
+							{
+								name : ' הדגשה',
+								legend : 'לחץ ${bold}'
+							}
+						]
+			}
+		],
+		contents : 'הוראות נגישות. לסגירה לחץ אסקייפ (ESC).'
 	}
 });
Index: /CKLangTool/trunk/test/_assets/translator2/he.js.correct.txt
===================================================================
--- /CKLangTool/trunk/test/_assets/translator2/he.js.correct.txt	(revision 7309)
+++ /CKLangTool/trunk/test/_assets/translator2/he.js.correct.txt	(revision 7310)
@@ -12,4 +12,48 @@
 		config : 'הדבק את הטקסט הבא לתוך הקובץ config.js',
 		predefined : 'קבוצות צבעים מוגדרות מראש'
+	},
+
+	accessibilityHelp :
+	{
+		title : 'הוראות נגישות',
+		legend :
+		[
+			{
+				name : 'כללי',
+				items :
+						[
+							{
+								name : 'סרגל הכלים',
+								legend:
+									'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.'  // MISSING
+							},
+							{
+								name : 'דיאלוגים (חלונות תשאול)'
+							}
+						]
+			},
+			{
+				name : 'פקודות',
+				items :
+						[
+							{
+								name : ' ביטול צעד אחרון',
+								legend :
+									'לחץ ${undo}'
+							},
+							{
+								name : ' חזרה על צעד אחרון',
+								legend : 
+									'Press ${redo}' // MISSING
+							},
+							{
+								name : ' הדגשה',
+								legend : 'לחץ ${bold}'
+							}
+						]
+			}
+		],
+		contents : 'הוראות נגישות. לסגירה לחץ אסקייפ (ESC).'
 	}
+
 });
