Index: /CKLangTool/trunk/_dev/build.xml
===================================================================
--- /CKLangTool/trunk/_dev/build.xml	(revision 3339)
+++ /CKLangTool/trunk/_dev/build.xml	(revision 3340)
@@ -14,6 +14,14 @@
 		<java fork="yes" classname="org.mozilla.javascript.tools.jsc.Main" failonerror="true">
 			<arg value="-debug" />
+			<arg value="-package" />
+			<arg value="cklangtool" />
 			<arg value="${source.dir}/langtool.js" />
+		</java>
+		<java fork="yes" classname="org.mozilla.javascript.tools.jsc.Main" failonerror="true">
+			<arg value="-debug" />
+			<arg value="-package" />
+			<arg value="cklangtool.includes" />
 			<arg value="${source.dir}/includes/cklangtool.js" />
+			<arg value="${source.dir}/includes/ckjpformat.js" />
 			<arg value="${source.dir}/includes/io.js" />
 		</java>
@@ -21,7 +29,8 @@
 
 	<target name="copy" depends="compile" description="copy files">
-		<copy file="${source.dir}/includes/cklangtool.class" tofile="${build.dir}/cklangtool.class" overwrite="true" />
-		<copy file="${source.dir}/includes/io.class" tofile="${build.dir}/io.class" overwrite="true" />
-		<copy file="${source.dir}/langtool.class" tofile="${build.dir}/langtool.class" overwrite="true" />
+		<copy file="${source.dir}/includes/cklangtool/includes/cklangtool.class" tofile="${build.dir}/cklangtool/includes/cklangtool.class" overwrite="true" />
+		<copy file="${source.dir}/includes/cklangtool/includes/ckjpformat.class" tofile="${build.dir}/cklangtool/includes/ckjpformat.class" overwrite="true" />
+		<copy file="${source.dir}/includes/cklangtool/includes/io.class" tofile="${build.dir}/cklangtool/includes/io.class" overwrite="true" />
+		<copy file="${source.dir}/cklangtool/langtool.class" tofile="${build.dir}/cklangtool/langtool.class" overwrite="true" />
 		<copy file="${rhino.jar}" tofile="${build.dir}/langtool.jar" overwrite="true" />
 	</target>
@@ -34,5 +43,5 @@
 			</fileset>
 			<manifest>
-				<attribute name="Main-Class" value="langtool" />
+				<attribute name="Main-Class" value="cklangtool.langtool" />
 			</manifest>
 		</jar>
@@ -53,7 +62,6 @@
 		<copy file="${build.dir}/langtool.jar" tofile="${bin.dir}/langtool.jar" overwrite="true" />
 		<delete dir="${build.dir}" />
-		<delete file="${source.dir}/langtool.class" />
-		<delete file="${source.dir}/includes/cklangtool.class" />
-		<delete file="${source.dir}/includes/io.class" />
+		<delete dir="${source.dir}/cklangtool/" />
+		<delete dir="${source.dir}/includes/cklangtool/" />
 	</target>
 
Index: /CKLangTool/trunk/_source/includes/ckjpformat.js
===================================================================
--- /CKLangTool/trunk/_source/includes/ckjpformat.js	(revision 3340)
+++ /CKLangTool/trunk/_source/includes/ckjpformat.js	(revision 3340)
@@ -0,0 +1,140 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+importPackage( java.util.regex );
+
+( function()
+{
+	CKLANGTOOL.jpformat = function()
+	{
+	};
+
+	/**
+	 * Language code of currently processed file (taken from
+	 * CKEDITOR.lang['code']).
+	 */
+	var languageCode;
+	var fileOverviewBlock;
+
+	function printObject( prefix, o )
+	{
+		var result = [];
+		
+		for ( var key in o )
+		{
+			var entry = o[ key ],
+				entryName = prefix ? ( prefix + '.' + key ) : key;
+			
+			if ( typeof entry == 'object' )
+				result.push( printObject( entryName, entry ) );
+			else
+				result.push( entryName + '=' + entry );
+		}
+		
+		return result.join( '\r\n' );
+	}
+	
+	function processFile( file )
+	{
+		var licenseInfo = "# Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r\n# For licensing, see LICENSE.html or http://ckeditor.com/license\r\n\r\n";
+		
+		fileHeader = getFileOverview( file.getAbsolutePath() ).replace( /\{.*?\}/g, '' ).replace( /@fileOverview/g, '' ).replace(/\s*(\/)?\s*(\*)+(\/)?/g , '').replace(/\s+/g, ' ');
+		
+		var result = CKLANGTOOL.loadLanguageFile( file );
+		
+		return licenseInfo + '#' + fileHeader + '\r\n\r\n' + printObject( '', result.translation );
+	}
+
+	var regexLib =
+	{
+		inlineComment :Pattern.compile( "^\\s*\\/\\/" ),
+		blockCommentStart :Pattern.compile( "\\/\\*" ),
+		blockCommentEnd :Pattern.compile( "\\*\\/" ),
+		fileOverview :Pattern.compile( " @fileOverview" ),
+	};
+	
+	/**
+	 * Returns an array with missing keys (already marked as //MISSING).
+	 */
+	function getFileOverview( file )
+	{
+		fileOverviewBlock = '/**\n* @fileOverview \n*/';
+
+		var inBlockComment = false;
+		var blockComment = [];
+		var matcher, line;
+		var lines = CKLANGTOOL.io.readFileIntoArray( file );
+
+		for ( var j = 0 ; j < lines.length ; j++ )
+		{
+			line = lines[ j ];
+			if ( !inBlockComment )
+			{
+				matcher = regexLib.inlineComment.matcher( line );
+				if ( matcher.find() )
+					continue;
+
+				matcher = regexLib.blockCommentStart.matcher( line );
+				if ( matcher.find() )
+				{
+					inBlockComment = true;
+					blockComment.push( line );
+					continue;
+				}
+			}
+			else
+			{
+				blockComment.push( line );
+
+				matcher = regexLib.blockCommentEnd.matcher( line );
+				if ( matcher.find() )
+				{
+					inBlockComment = false;
+
+					matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
+					if ( matcher.find() )
+						fileOverviewBlock = blockComment.join( "\n" );
+					blockComment = [];
+				}
+			}
+		}
+
+		return fileOverviewBlock;
+	}
+	
+	CKLANGTOOL.jpformat.prototype =
+	{
+		run : function()
+		{
+			var children = CKLANGTOOL.languageDir.list();
+			var errors, file, status = [];
+			var foundFiles = false;
+			var fileHeader = "";
+
+			for ( var i = 0 ; i < children.length ; i++ )
+			{
+				if ( CKLANGTOOL.io.getExtension( children[ i ] ) != "js" )
+					continue;
+
+				file = new File( CKLANGTOOL.languageDir, children[ i ] );
+				if ( file.isFile() )
+				{
+					print( "Processing " + file.getAbsolutePath() );
+					
+					CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.destinationDir, children[i].replaceAll( '.js', '.txt' ) ), processFile(file), false );
+					
+					foundFiles = true;
+				}
+			}
+
+			if ( !foundFiles )
+			{
+				print( "WARNING: language files not found." );
+			}
+
+			print( "Process completed." );
+		}
+	};
+})();
Index: /CKLangTool/trunk/_source/includes/cklangtool.js
===================================================================
--- /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 3339)
+++ /CKLangTool/trunk/_source/includes/cklangtool.js	(revision 3340)
@@ -8,11 +8,87 @@
 var CKLANGTOOL =
 {
-	languageDir :"",
-	templateFile :"",
+	isCompiled : false,
+	languageDir : "",
+	templateFile : "",
+	operation : "default",
 	/**
 	 * Holds the content of en.js language file where strings are replaced with
 	 * special placeholders: #ckeditor_translation.placeholder.key#.
 	 */
-	template :""
+	template : "",
+	path : "",
+	
+	load : function( className )
+	{
+		if ( CKLANGTOOL.isCompiled )
+		{
+			loadClass( className );
+		}
+		else
+		{
+			var path = className;
+			path = path.replace( /^cklangtool\./, "_source/" );
+			path = path.replace( /\./g, '/' ) + '.js';
+
+			load( CKLANGTOOL.path + path );
+		}
+	}	
+};
+
+/**
+ * Load language file and return an object with the whole translation.
+ */
+CKLANGTOOL.loadLanguageFile = function( file )
+{
+	var translationCode = 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file );
+
+	var cx = Context.enter(), scope = cx.initStandardObjects();
+
+	cx.evaluateString( scope, translationCode, file.getName(), 1, null );
+
+	try
+	{
+		var languageCode = '';
+
+		/*
+		 * Get the number of variables in parent scope.
+		 */
+		var size = 0;
+		for ( var i in scope )
+		{
+			size++;
+		}
+
+		/*
+		 * If there is more than one variable, then it's not a CKEDITOR language file.
+		 */
+		if ( size > 1 )
+		{
+			/**
+			 * Return the first variable from parent scope different than
+			 * CKEDITOR.
+			 */
+			for ( var i in scope )
+			{
+				if ( i != "CKEDITOR" )
+					return { 'languageCode' : languageCode, 'translation' : scope[i] };
+			}
+		}
+		else
+		{
+			/*
+			 * Return the first entry from scope.CKEDITOR.lang object
+			 */
+			for ( var i in scope.CKEDITOR.lang )
+			{
+				languageCode = i;
+				return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i] };
+			}
+		}
+	}
+	catch ( e )
+	{
+		throw ( "Language file is invalid (" + file.getAbsolutePath() + ")" );
+	}
 };
 
@@ -49,61 +125,4 @@
 		{
 			throw ("Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message);
-		}
-	}
-
-	/**
-	 * Load language file and return an object with the whole translation.
-	 */
-	function loadLanguageFile( file )
-	{
-		var translationCode = 'var CKEDITOR = { lang : {} }; ' + CKLANGTOOL.io.readFile( file );
-
-		var cx = Context.enter(), scope = cx.initStandardObjects();
-
-		cx.evaluateString( scope, translationCode, file.getName(), 1, null );
-
-		try
-		{
-			languageCode = '';
-
-			/*
-			 * Get the number of variables in parent scope.
-			 */
-			var size = 0;
-			for ( var i in scope )
-			{
-				size++;
-			}
-
-			/*
-			 * If there is more than one variable, then it's not a CKEDITOR language file.
-			 */
-			if ( size > 1 )
-			{
-				/**
-				 * Return the first variable from parent scope different than
-				 * CKEDITOR.
-				 */
-				for ( var i in scope )
-				{
-					if ( i != "CKEDITOR" )
-						return scope[ i ];
-				}
-			}
-			else
-			{
-				/*
-				 * Return the first entry from scope.CKEDITOR.lang object
-				 */
-				for ( var i in scope.CKEDITOR.lang )
-				{
-					languageCode = i;
-					return scope.CKEDITOR.lang[ i ];
-				}
-			}
-		}
-		catch ( e )
-		{
-			throw ("Language file is invalid (" + file.getAbsolutePath() + ")");
 		}
 	}
@@ -472,5 +491,4 @@
 	function processFile( file )
 	{
-		translation = loadLanguageFile( file );
 		var missingKeys = analyzeLanguageFile( file );
 		var matchResult, replacement, translationKey;
@@ -478,4 +496,8 @@
 		var matcher = regexLib.translation.matcher( string );
 		var found = 0, missing = 0;
+		var result = CKLANGTOOL.loadLanguageFile( file );
+		var translation = result.translation;
+
+		languageCode = result.languageCode;
 
 		while ( matcher.find() )
@@ -556,5 +578,6 @@
 		{
 			CKLANGTOOL.template = createTemplate( CKLANGTOOL.templateFile );
-			CKLANGTOOL.englishTranslation = loadLanguageFile( CKLANGTOOL.templateFile );
+			var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile ); 
+			CKLANGTOOL.englishTranslation = result.translation; 
 
 			var children = CKLANGTOOL.languageDir.list();
Index: /CKLangTool/trunk/_source/langtool.js
===================================================================
--- /CKLangTool/trunk/_source/langtool.js	(revision 3339)
+++ /CKLangTool/trunk/_source/langtool.js	(revision 3340)
@@ -14,8 +14,9 @@
 var isCompiled = true;
 var command = "java -cp js.jar org.mozilla.javascript.tools.shell.Main langtool.js";
+var resource = JavaAdapter( org.mozilla.javascript.Parser )["class"].getResource( "/org/mozilla/javascript" ).toString();
 
 try
 {
-	java.lang.Class.forName( "langtool" );
+	java.lang.Class.forName( "cklangtool.langtool" );
 }
 catch ( e )
@@ -23,4 +24,6 @@
 	isCompiled = false;
 }
+
+var cklangtoolPath = '';
 
 if ( isCompiled )
@@ -31,6 +34,5 @@
 	};
 
-	loadClass( "cklangtool" );
-	loadClass( "io" );
+	loadClass( 'cklangtool.includes.cklangtool' );
 
 	var resource = JavaAdapter( org.mozilla.javascript.Parser )["class"].getResource( "/org/mozilla/javascript" ).toString();
@@ -42,10 +44,40 @@
 else
 {
-	load( "includes/cklangtool.js" );
-	load( "includes/io.js" );
+	cklangtoolPath = resource.replaceFirst( "^jar:", '' ).replaceFirst( "\/js\.jar\!\/org\/mozilla\/javascript$", '' )
+			.replaceAll( "_dev.{1}_thirdparty.{1}rhino", "" );
+
+	load( cklangtoolPath + "_source/includes/cklangtool.js" );
+
+	CKLANGTOOL.path = cklangtoolPath;
 }
 
-if ( !arguments[0] )
-	error( 'Usage: ' + command + ' [lang_dir]' );
+CKLANGTOOL.isCompiled = isCompiled;
+CKLANGTOOL.load( 'cklangtool.includes.ckjpformat' );
+CKLANGTOOL.load( 'cklangtool.includes.io' );
+
+if ( !arguments[0] || arguments[0] == '-help' || arguments[0] == '/?' )
+	error( 'Usage: ' + command + ' lang_dir [-jpformat=dest_dir]'
+			+ '\n\n CKLangTool corrects translation files and creates report about missing translations.'
+			+ '\n\n -jpformat  Convert files to java properties format and save them in dest_dir.\n' );
+
+for ( var i = 0 ; i < arguments.length ; i++ )
+{
+	if ( arguments[i].indexOf( "-jpformat=" ) != -1 )
+	{
+		var destDir = arguments[i].substring( arguments[i].indexOf( "=" ) + 1 );
+		CKLANGTOOL.destinationDir = new File( destDir );
+		if ( CKLANGTOOL.destinationDir.exists() )
+			error( 'Destination directory already exists: ' + CKLANGTOOL.destinationDir.getAbsolutePath() );
+		else
+			CKLANGTOOL.destinationDir.mkdir();
+		CKLANGTOOL.operation = "jpformat";
+	}
+}
+
+if ( arguments[0] == '-test' && !isCompiled )
+{
+	CKLANGTOOL.load( 'test.test' );
+	quit();
+}
 
 CKLANGTOOL.languageDir = new File( arguments[0] );
@@ -68,6 +100,14 @@
 	try
 	{
-		var translator = new CKLANGTOOL.translator();
-		translator.run();
+		if ( CKLANGTOOL.operation == "jpformat" )
+		{
+			var jpformat = new CKLANGTOOL.jpformat();
+			jpformat.run();
+		}
+		else
+		{
+			var translator = new CKLANGTOOL.translator();
+			translator.run();
+		}
 	}
 	catch ( e )
