Index: /CKEditor/trunk/_source/core/config.js
===================================================================
--- /CKEditor/trunk/_source/core/config.js	(revision 3715)
+++ /CKEditor/trunk/_source/core/config.js	(revision 3716)
@@ -150,6 +150,5 @@
 	 * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
 	 */
-
-	plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,contextmenu,elementspath,enterkey,entities,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,resize,save,scayt,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc',
+	plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,contextmenu,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,save,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc',
 
 	/**
Index: /CKEditor/trunk/_source/plugins/dialog/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/dialog/plugin.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/dialog/plugin.js	(revision 3716)
@@ -760,4 +760,5 @@
 						( this._.pageCount > 0 ? ' cke_last' : 'cke_first' ),
 						titleHtml,
+						( !!contents.hidden ? ' style="display:none"' : '' ),
 						' id="', contents.id + '_', CKEDITOR.tools.getNextNumber(), '"' +
 						' href="javascript:void(0)"',
@@ -872,4 +873,15 @@
 		{
 			return this._.element;
+		},
+
+		/**
+		 * Gets the name of the dialog.
+		 * @returns {String} The name of this dialog.
+		 * @example
+		 * var dialogName = dialogObj.getName();
+		 */
+		getName : function()
+		{
+			return this._.name;
 		},
 
@@ -1790,4 +1802,6 @@
 			 * 	<li><strong>title</strong> (Optional) The popup tooltip for the UI
 			 * 	element.</li>
+			 * 	<li><strong>hidden</strong> (Optional) A flag that tells if the element
+			 * 	should be initially visible.</li>
 			 * 	<li><strong>className</strong> (Optional) Additional CSS class names
 			 * 	to add to the UI element. Separated by space.</li>
@@ -1863,4 +1877,6 @@
 				for ( i in styles )
 					styleStr.push( i + ':' + styles[i] );
+				if ( elementDefinition.hidden )
+					styleStr.push( 'display:none' );
 				for ( i = styleStr.length - 1 ; i >= 0 ; i-- )
 				{
@@ -1869,5 +1885,5 @@
 				}
 				if ( styleStr.length > 0 )
-					attributes.style = ( attributes.style || '' ) + styleStr.join( '; ' );
+					attributes.style = ( attributes.style ? ( attributes.style + '; ' ) : '' ) + styleStr.join( '; ' );
 
 				// Write the attributes.
Index: /CKEditor/trunk/_source/plugins/dialogui/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/dialogui/plugin.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/dialogui/plugin.js	(revision 3716)
@@ -655,10 +655,14 @@
 
 				var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition );
+				var onClick = myDefinition.onClick; 
 				myDefinition.className = ( myDefinition.className ? myDefinition.className + ' ' : '' ) + 'cke_dialog_ui_button';
 				myDefinition.onClick = function( evt )
 				{
 					var target = elementDefinition[ 'for' ];		// [ pageId, elementId ]
-					dialog.getContentElement( target[0], target[1] ).submit();
-					this.disable();
+					if ( !onClick || onClick.call( this, evt ) !== false )
+					{
+						dialog.getContentElement( target[0], target[1] ).submit();
+						this.disable();
+					}
 				};
 
@@ -1198,4 +1202,14 @@
 
 				/**
+				 * Get the action assigned to the form.
+				 * @returns {String} The value of the action.
+				 * @example
+				 */
+				getAction : function( action )
+				{
+					return this.getInputElement().getParent().$.action;
+				},
+
+				/**
 				 * Redraws the file input and resets the file path in the file input.
 				 * The redraw logic is necessary because non-IE browsers tend to clear
Index: /CKEditor/trunk/_source/plugins/filebrowser/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/filebrowser/plugin.js	(revision 3716)
+++ /CKEditor/trunk/_source/plugins/filebrowser/plugin.js	(revision 3716)
@@ -0,0 +1,383 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview The "filebrowser" plugin, it adds support for file uploads and
+ *               browsing.
+ * 
+ * When file is selected inside of the file browser or uploaded, its url is
+ * inserted automatically to a field, which is described in the 'filebrowser'
+ * attribute. To specify field that should be updated, pass the tab id and
+ * element id, separated with a colon.
+ * 
+ * Example 1: (Browse)
+ * 
+ * <pre>
+ * {
+ * 	type : 'button',
+ * 	id : 'browse',
+ * 	filebrowser : 'tabId:elementId',
+ * 	label : editor.lang.common.browseServer
+ * }
+ * </pre>
+ * 
+ * If you set the 'filebrowser' attribute on any element other than
+ * 'fileButton', the 'Browse' action will be triggered.
+ * 
+ * Example 2: (Quick Upload)
+ * 
+ * <pre>
+ * {
+ * 	type : 'fileButton',
+ * 	id : 'uploadButton',
+ * 	filebrowser : 'tabId:elementId',
+ * 	label : editor.lang.common.uploadSubmit,
+ * 	'for' : [ 'upload', 'upload' ]
+ * }
+ * </pre>
+ * 
+ * If you set the 'filebrowser' attribute on a fileButton element, the
+ * 'QuickUpload' action will be executed.
+ * 
+ * Filebrowser plugin also supports more advanced configuration (through
+ * javascript object).
+ * 
+ * The following settings are supported:
+ * 
+ * <pre>
+ *  [action] - Browse or QuickUpload
+ *  [target] - field to update, tabId:elementId
+ *  [params] - additional arguments to be passed to the server connector (optional)
+ *  [onSelect] - function to execute when file is selected/uploaded (optional)
+ *  [url] - the URL to be called (optional)
+ * </pre>
+ * 
+ * Example 3: (Quick Upload)
+ * 
+ * <pre>
+ * {
+ * 	type : 'fileButton',
+ * 	label : editor.lang.common.uploadSubmit,
+ * 	id : 'buttonId',
+ * 	filebrowser :
+ * 	{
+ * 		action : 'QuickUpload', //required
+ * 		target : 'tab1:elementId', //required
+ * 		params : //optional
+ * 		{
+ * 			type : 'Files',
+ * 			currentFolder : '/folder/'
+ * 		},
+ * 		onSelect : function( fileUrl, errorMessage ) //optional 
+ * 		{
+ * 			// Do not call the built-in selectFuntion 
+ * 			// return false;
+ * 		}
+ * 	},
+ * 	'for' : [ 'tab1', 'myFile' ]
+ * }
+ * </pre>
+ * 
+ * Suppose we have a file element with id 'myFile', text field with id
+ * 'elementId' and a fileButton. If filebowser.url is not specified explicitly,
+ * form action will be set to 'filebrowser[DialogName]UploadUrl' or, if not
+ * specified, to 'filebrowserUploadUrl'. Additional parameters from 'params'
+ * object will be added to the query string. It is possible to create your own
+ * uploadHandler and cancel the built-in updateTargetElement command.
+ * 
+ * Example 4: (Browse)
+ * 
+ * <pre>
+ * {
+ * 	type : 'button',
+ * 	id : 'buttonId',
+ * 	label : editor.lang.common.browseServer,
+ * 	filebrowser :
+ * 	{
+ * 		action : 'Browse',
+ * 		url : '/ckfinder/ckfinder.html&amp;type=Images',
+ * 		target : 'tab1:elementId'
+ * 	}
+ * }
+ * </pre>
+ * 
+ * In this example, after pressing a button, file browser will be opened in a
+ * popup. If we don't specify filebrowser.url attribute,
+ * 'filebrowser[DialogName]BrowseUrl' or 'filebrowserBrowseUrl' will be used.
+ * After selecting a file in a file browser, an element with id 'elementId' will
+ * be updated. Just like in the third example, a custom 'onSelect' function may be 
+ * defined.
+ */
+( function()
+{
+	/**
+	 * Adds (additional) arguments to given url.
+	 * 
+	 * @param {String}
+	 *            url The url.
+	 * @param {Object}
+	 *            params Additional parameters.
+	 */
+	function addQueryString( url, params )
+	{
+		var queryString = [];
+
+		if ( !params )
+			return url;
+		else
+		{
+			for ( var i in params )
+				queryString.push( i + "=" + encodeURIComponent( params[ i ] ) );
+		}
+
+		return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" );
+	}
+
+	/**
+	 * Make a string's first character uppercase.
+	 * 
+	 * @param {String}
+	 *            str String.
+	 */
+	function ucFirst( str )
+	{
+		str += '';
+		var f = str.charAt( 0 ).toUpperCase();
+		return f + str.substr( 1 );
+	}
+
+	/**
+	 * The onlick function assigned to the 'Browse Server' button. Opens the
+	 * file browser and updates target field when file is selected.
+	 * 
+	 * @param {CKEDITOR.event}
+	 *            evt The event object.
+	 */
+	function browseServer( evt )
+	{
+		var dialog = this.getDialog();
+		var editor = dialog.getParentEditor();
+
+		editor._.filebrowserSe = this;
+
+		var width = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowWidth' ]
+				|| editor.config.filebrowserWindowWidth || '80%';
+		var height = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowHeight' ]
+				|| editor.config.filebrowserWindowHeight || '70%';
+
+		var params = this.filebrowser.params || {};
+		params.CKEditor = editor.name;
+		params.CKEditorFuncNum = editor._.filebrowserFn;
+		if ( !params.langCode )
+			params.langCode = editor.langCode;
+
+		url = addQueryString( this.filebrowser.url, params );
+		editor.popup( url, width, height );
+	}
+
+	/**
+	 * The onlick function assigned to the 'Upload' button. Makes the final
+	 * decision whether form is really submitted and updates target field when
+	 * file is uploaded.
+	 * 
+	 * @param {CKEDITOR.event}
+	 *            evt The event object.
+	 */
+	function uploadFile( evt )
+	{
+		var dialog = this.getDialog();
+		var editor = dialog.getParentEditor();
+
+		editor._.filebrowserSe = this;
+
+		// If user didn't select the file, stop the upload.
+		if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getInputElement().$.value )
+			return false;
+
+		if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getAction() )
+			return false;
+
+		return true;
+	}
+
+	/**
+	 * Setups the file element.
+	 * 
+	 * @param {CKEDITOR.ui.dialog.file}
+	 *            fileInput The file element used during file upload.
+	 * @param {Object}
+	 *            filebrowser Object containing filebrowser settings assigned to
+	 *            the fileButton associated with this file element.
+	 */
+	function setupFileElement( editor, fileInput, filebrowser )
+	{
+		var params = filebrowser.params || {};
+		params.CKEditor = editor.name;
+		params.CKEditorFuncNum = editor._.filebrowserFn;
+		if ( !params.langCode )
+			params.langCode = editor.langCode;
+
+		fileInput.action = addQueryString( filebrowser.url, params );
+		fileInput.filebrowser = filebrowser;
+	}
+
+	/**
+	 * Traverse through the content definition and attach filebrowser to
+	 * elements with 'filebrowser' attribute.
+	 * 
+	 * @param String
+	 *            dialogName Dialog name.
+	 * @param {CKEDITOR.dialog.dialogDefinitionObject}
+	 *            definition Dialog definition.
+	 * @param {Array}
+	 *            elements Array of {@link CKEDITOR.dialog.contentDefinition}
+	 *            objects.
+	 */
+	function attachFileBrowser( editor, dialogName, definition, elements )
+	{
+		var element, fileInput;
+
+		for ( var i in elements )
+		{
+			element = elements[ i ];
+
+			if ( element.type == 'hbox' || element.type == 'vbox' )
+				attachFileBrowser( editor, dialogName, definition, element.children );
+
+			if ( !element.filebrowser )
+				continue;
+
+			if ( typeof element.filebrowser == 'string' )
+			{
+				var fb =
+				{
+					action : ( element.type == 'fileButton' ) ? 'QuickUpload' : 'Browse',
+					target : element.filebrowser
+				};
+				element.filebrowser = fb;
+			}
+
+			if ( element.filebrowser.action == 'Browse' )
+			{
+				var url = element.filebrowser.url || editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'BrowseUrl' ] 
+							|| editor.config.filebrowserBrowseUrl;
+
+				if ( url )
+				{
+					element.onClick = browseServer;
+					element.filebrowser.url = url;
+					element.hidden = false;
+				}
+			}
+			else if ( element.filebrowser.action == 'QuickUpload' && element[ 'for' ] )
+			{
+				var url =  element.filebrowser.url || editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'UploadUrl' ]
+							|| editor.config.filebrowserUploadUrl;
+
+				if ( url )
+				{
+					element.onClick = uploadFile;
+					element.filebrowser.url = url;
+					element.hidden = false;
+					setupFileElement( editor, definition.getContents( element[ 'for' ][ 0 ] ).get( element[ 'for' ][ 1 ] ), element.filebrowser );
+				}
+			}
+		}
+	}
+
+	/**
+	 * Updates the target element with the url of uploaded/selected file.
+	 * 
+	 * @param {String}
+	 *            url The url of a file.
+	 */
+	function updateTargetElement( url, sourceElement )
+	{
+		var dialog = sourceElement.getDialog();
+		var targetElement = sourceElement.filebrowser.target || null;
+		url = url.replace( /#/g, '%23' );
+
+		// If there is a reference to targetElement, update it.
+		if ( targetElement )
+		{
+			var target = targetElement.split( ':' );
+			var element = dialog.getContentElement( target[ 0 ], target[ 1 ] );
+			if ( element )
+			{
+				element.setValue( url );
+				dialog.selectPage( target[ 0 ] );
+			}
+		}
+	}
+
+	/**
+	 * Returns true if filebrowser is configured in one of the elements.   
+	 * 
+	 * @param {CKEDITOR.dialog.dialogDefinitionObject}
+	 *            definition Dialog definition.
+	 * @param String
+	 *            tabId The tab id where element(s) can be found.
+	 * @param String
+	 *            elementId The element id (or ids, separated with a semicolon) to check.
+	 */
+	function isConfigured( definition, tabId, elementId )
+	{
+		if ( elementId.indexOf( ";" ) !== -1 )
+		{
+			var ids = elementId.split( ";" );
+			for ( var i = 0 ; i < ids.length ; i++ )
+			{
+				if ( isConfigured( definition, tabId, ids[i]) )
+					return true;
+			}
+			return false;
+		}
+		
+		return ( definition.getContents( tabId ).get( elementId ).filebrowser && definition.getContents( tabId ).get( elementId ).filebrowser.url );
+	}
+
+	function setUrl( fileUrl, data )
+	{
+		var dialog = this._.filebrowserSe.getDialog(),
+			targetInput = this._.filebrowserSe[ 'for' ],
+			onSelect = this._.filebrowserSe.filebrowser.onSelect;
+
+		if ( targetInput )
+			dialog.getContentElement( targetInput[ 0 ], targetInput[ 1 ] ).reset();
+
+		if ( onSelect && onSelect.call( this._.filebrowserSe, fileUrl, data ) === false )
+			return;
+
+		// The "data" argument may be used to pass the error message to the editor.   
+		if ( typeof data == 'string' && data )
+			alert( data );
+
+		if ( fileUrl )
+			updateTargetElement( fileUrl, this._.filebrowserSe );
+	}
+
+	CKEDITOR.plugins.add( 'filebrowser',
+	{
+		init : function( editor, pluginPath )
+		{
+			editor._.filebrowserFn = CKEDITOR.tools.addFunction( setUrl, editor );
+
+			CKEDITOR.on( 'dialogDefinition', function( evt )
+			{
+				// Associate filebrowser to elements with 'filebrowser' attribute.
+				for ( var i in evt.data.definition.contents )
+				{
+					attachFileBrowser( evt.editor, evt.data.name, evt.data.definition, evt.data.definition.contents[ i ].elements );
+					if ( evt.data.definition.contents[ i ].hidden && evt.data.definition.contents[ i ].filebrowser )
+					{
+						evt.data.definition.contents[ i ].hidden = 
+							!isConfigured( evt.data.definition, evt.data.definition.contents[ i ][ 'id' ], evt.data.definition.contents[ i ].filebrowser );
+					}
+				}
+			} );
+		}
+	} );
+
+} )();
Index: /CKEditor/trunk/_source/plugins/flash/dialogs/flash.js
===================================================================
--- /CKEditor/trunk/_source/plugins/flash/dialogs/flash.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/flash/dialogs/flash.js	(revision 3716)
@@ -182,12 +182,4 @@
 			minWidth : 420,
 			minHeight : 310,
-			onLoad : function()
-			{
-				if ( !editor.config.flashUploadTab )
-					this.hidePage( 'Upload' );		// Hide Upload tab.
-
-				if ( !editor.config.flashBrowseServer )
-					this.getContentElement( 'info', 'browse' ).getElement().hide();
-			},
 			onShow : function()
 			{
@@ -348,4 +340,6 @@
 											type : 'button',
 											id : 'browse',
+											filebrowser : 'info:src',
+											hidden : true,
 											align : 'center',
 											label : editor.lang.common.browseServer
@@ -439,4 +433,6 @@
 				{
 					id : 'Upload',
+					hidden : true,
+					filebrowser : 'uploadButton',
 					label : editor.lang.common.upload,
 					elements :
@@ -446,5 +442,4 @@
 							id : 'upload',
 							label : editor.lang.common.upload,
-							action : editor.config.image_uploadAction,
 							size : 38
 						},
@@ -453,4 +448,5 @@
 							id : 'uploadButton',
 							label : editor.lang.common.uploadSubmit,
+							filebrowser : 'info:src',
 							'for' : [ 'Upload', 'upload' ]
 						}
Index: /CKEditor/trunk/_source/plugins/flash/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/flash/plugin.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/flash/plugin.js	(revision 3716)
@@ -143,8 +143,4 @@
 CKEDITOR.tools.extend( CKEDITOR.config,
 {
-	flashUploadTab : true,
-	flashUploadAction : 'nowhere.php',
-	flashBrowseServer : true,
-
 	/**
 	 * Save as EMBED tag only. This tag is unrecommended.
Index: /CKEditor/trunk/_source/plugins/image/dialogs/image.js
===================================================================
--- /CKEditor/trunk/_source/plugins/image/dialogs/image.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/image/dialogs/image.js	(revision 3716)
@@ -446,14 +446,6 @@
 											align : 'center',
 											label : editor.lang.common.browseServer,
-											onLoad : function()
-											{
-												var dialog = this.getDialog();
-												if ( !dialog.getParentEditor().config.image_browseServer )
-													dialog.getContentElement( 'info', 'browse' ).getElement().hide();
-											},
-											onClick : function()
-											{
-
-											}
+											hidden : true,
+											filebrowser : 'info:txtUrl'
 										}
 									]
@@ -931,9 +923,8 @@
 							type : 'button',
 							id : 'browse',
+							filebrowser : 'Link:txtUrl',
 							style : 'float:right',
-							label : editor.lang.common.browseServer,
-							onClick : function()
-							{
-							}
+							hidden : true,
+							label : editor.lang.common.browseServer
 						},
 						{
@@ -968,4 +959,6 @@
 				{
 					id : 'Upload',
+					hidden : true,
+					filebrowser : 'uploadButton',
 					label : editor.lang.image.upload,
 					elements :
@@ -975,5 +968,4 @@
 							id : 'upload',
 							label : editor.lang.image.btnUpload,
-							action : editor.config.image_uploadAction,
 							size : 38
 						},
@@ -981,4 +973,5 @@
 							type : 'fileButton',
 							id : 'uploadButton',
+							filebrowser : 'info:txtUrl',
 							label : editor.lang.image.btnUpload,
 							'for' : [ 'Upload', 'upload' ]
Index: /CKEditor/trunk/_source/plugins/image/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/image/plugin.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/image/plugin.js	(revision 3716)
@@ -55,16 +55,3 @@
 } );
 
-/**
- * Show Browse Server button.
- * @type Boolean
- * @default true
- */
-CKEDITOR.config.image_browseServer = true;
-
-/**
- * Upload action attribute.
- * @type URL
- */
-CKEDITOR.config.image_uploadAction = 'nowhere.php';
-
 CKEDITOR.config.image_removeLinkByEmptyURL = true;
Index: /CKEditor/trunk/_source/plugins/link/dialogs/link.js
===================================================================
--- /CKEditor/trunk/_source/plugins/link/dialogs/link.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/link/dialogs/link.js	(revision 3716)
@@ -37,10 +37,12 @@
 		var dialog = this.getDialog(),
 			partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],
-			typeValue = this.getValue();
+			typeValue = this.getValue(),
+			uploadInitiallyHidden = dialog.definition.getContents( 'upload' ).hidden;
+	
 		if ( typeValue == 'url' )
 		{
 			if ( editor.config.linkShowTargetTab )
 				dialog.showPage( 'target' );
-			if ( editor.config.linkUploadTab )
+			if ( !uploadInitiallyHidden )
 				dialog.showPage( 'upload' );
 		}
@@ -48,5 +50,6 @@
 		{
 			dialog.hidePage( 'target' );
-			dialog.hidePage( 'upload' );
+			if ( !uploadInitiallyHidden )
+				dialog.hidePage( 'upload' );
 		}
 
@@ -389,4 +392,6 @@
 								type : 'button',
 								id : 'browse',
+								hidden : 'true',
+								filebrowser : 'info:url',
 								label : editor.lang.common.browseServer
 							}
@@ -816,4 +821,6 @@
 				label : editor.lang.link.upload,
 				title : editor.lang.link.upload,
+				hidden : true,
+				filebrowser : 'uploadButton',
 				elements :
 				[
@@ -822,5 +829,4 @@
 						id : 'upload',
 						label : editor.lang.common.upload,
-						action : editor.config.linkUploadAction,
 						size : 38
 					},
@@ -829,4 +835,5 @@
 						id : 'uploadButton',
 						label : editor.lang.common.uploadSubmit,
+						filebrowser : 'info:url',
 						'for' : [ 'upload', 'upload' ]
 					}
@@ -1040,5 +1047,5 @@
 					var protocol = ( data.url && data.url.protocol != undefined ) ? data.url.protocol : 'http://',
 						url = ( data.url && data.url.url ) || '';
-					attributes._cke_saved_href = protocol + url;
+					attributes._cke_saved_href = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;
 					break;
 				case 'anchor':
@@ -1196,12 +1203,6 @@
 		onLoad : function()
 		{
-			if ( !editor.config.linkUploadTab )
-				this.hidePage( 'upload' );		//Hide Upload tab.
-
 			if ( !editor.config.linkShowAdvancedTab )
 				this.hidePage( 'advanced' );		//Hide Advanded tab.
-
-			if ( !editor.config.linkBrowseServer )
-				this.getContentElement( 'info', 'browse' ).getElement().hide();
 
 			if ( !editor.config.linkShowTargetTab )
Index: /CKEditor/trunk/_source/plugins/link/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/link/plugin.js	(revision 3715)
+++ /CKEditor/trunk/_source/plugins/link/plugin.js	(revision 3716)
@@ -184,7 +184,4 @@
 CKEDITOR.tools.extend( CKEDITOR.config,
 {
-	linkUploadTab : true,
-	linkBrowseServer : true,
-	linkUploadAction : 'nowhere.php',
 	linkShowAdvancedTab : true,
 	linkShowTargetTab : true
Index: /CKEditor/trunk/_source/plugins/popup/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/popup/plugin.js	(revision 3716)
+++ /CKEditor/trunk/_source/plugins/popup/plugin.js	(revision 3716)
@@ -0,0 +1,62 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+CKEDITOR.plugins.add( 'popup');
+
+CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
+{
+	/**
+	 * Opens Browser in a popup. The "width" and "height" parameters accept
+	 * numbers (pixels) or percent (of screen size) values.
+	 * @param {String} url The url of the external file browser.
+	 * @param {String} width Popup window width.
+	 * @param {String} height Popup window height.
+	 */
+	popup : function( url, width, height )
+	{
+		width = width || '80%';
+		height = height || '70%';
+
+		if ( typeof width == 'string' && width.length > 1 && width.substr( width.length - 1, 1 ) == '%' )
+			width = parseInt( window.screen.width * parseInt( width, 10 ) / 100, 10 );
+
+		if ( typeof height == 'string' && height.length > 1 && height.substr( height.length - 1, 1 ) == '%' )
+			height = parseInt( window.screen.height * parseInt( height, 10 ) / 100, 10 );
+
+		if ( width < 640 )
+			width = 640;
+
+		if ( height < 420 )
+			height = 420;
+
+		var top = parseInt( ( window.screen.height - height ) / 2, 10 ),
+			left = parseInt( ( window.screen.width  - width ) / 2, 10 ),
+			options = 'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes' +
+			',width='  + width +
+			',height=' + height +
+			',top='  + top +
+			',left=' + left;
+
+		var popupWindow = window.open( '', null, options, true );
+
+		// Blocked by a popup blocker.
+		if ( !popupWindow )
+			return false;
+
+		try
+		{
+			popupWindow.moveTo( left, top );
+			popupWindow.resizeTo( width, height );
+			popupWindow.focus();
+			popupWindow.location.href = url;
+		}
+		catch (e)
+		{
+			popupWindow = window.open( url, null, options, true );
+		}
+
+		return true ;
+	}
+});
Index: /CKEditor/trunk/ckeditor.pack
===================================================================
--- /CKEditor/trunk/ckeditor.pack	(revision 3715)
+++ /CKEditor/trunk/ckeditor.pack	(revision 3716)
@@ -154,4 +154,5 @@
 					'_source/plugins/pastefromword/plugin.js',
 					'_source/plugins/pastetext/plugin.js',
+					'_source/plugins/popup/plugin.js',
 					'_source/plugins/preview/plugin.js',
 					'_source/plugins/print/plugin.js',
@@ -159,4 +160,5 @@
 					'_source/plugins/resize/plugin.js',
 					'_source/plugins/save/plugin.js',
+					'_source/plugins/filebrowser/plugin.js',
 					'_source/plugins/scayt/plugin.js',
 					'_source/plugins/smiley/plugin.js',
