diff --git a/adminzone/pages/modules/admin_addons.php b/adminzone/pages/modules/admin_addons.php
index 070a83b..c47370a 100644
--- a/adminzone/pages/modules/admin_addons.php
+++ b/adminzone/pages/modules/admin_addons.php
@@ -197,12 +197,17 @@ class Module_admin_addons
 
 		require_code('form_templates');
 
-		$required=false;
-		$javascript='standardAlternateFields(\'file\',\'url\');';
-
 		$fields=new ocp_tempcode();
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',$required,NULL,NULL,true,'tar'));
-		$fields->attach(form_input_tree_list(do_lang_tempcode('DOWNLOAD'),do_lang_tempcode('DESCRIPTION_DOWNLOAD_OCPORTALCOM'),'url',NULL,'choose_ocportalcom_addon',array(),$required));
+		$set_name='addon';
+		$required=true;
+		$set_title=do_lang_tempcode('SOURCE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,'tar'));
+
+		$field_set->attach(form_input_tree_list(do_lang_tempcode('DOWNLOAD'),do_lang_tempcode('DESCRIPTION_DOWNLOAD_OCPORTALCOM'),'url',NULL,'choose_ocportalcom_addon',array(),false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
 
 		$hidden=new ocp_tempcode();
 		handle_max_file_size($hidden);
@@ -222,7 +227,7 @@ class Module_admin_addons
 			$text->attach(paragraph(do_lang_tempcode(is_null($config_url)?'MAXIMUM_UPLOAD':'MAXIMUM_UPLOAD_STAFF',escape_html(($max>10.0)?integer_format(intval($max)):float_format($max)),escape_html($config_url))));
 		}
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'7f50130c5a46e0f6e8a95e936ce7bf47','SKIP_VALIDATION'=>true,'HIDDEN'=>$hidden,'TITLE'=>$title,'SUBMIT_NAME'=>$submit_name,'FIELDS'=>$fields,'TEXT'=>$text,'URL'=>$post_url,'JAVASCRIPT'=>$javascript));
+		return do_template('FORM_SCREEN',array('_GUID'=>'7f50130c5a46e0f6e8a95e936ce7bf47','SKIP_VALIDATION'=>true,'HIDDEN'=>$hidden,'TITLE'=>$title,'SUBMIT_NAME'=>$submit_name,'FIELDS'=>$fields,'TEXT'=>$text,'URL'=>$post_url));
 	}
 
 	/**
diff --git a/adminzone/pages/modules/admin_import.php b/adminzone/pages/modules/admin_import.php
index f0f8417..47083bc 100644
--- a/adminzone/pages/modules/admin_import.php
+++ b/adminzone/pages/modules/admin_import.php
@@ -463,7 +463,7 @@ class Module_admin_import
 		require_code('form_templates');
 
 		// Selector for the content to import
-		$javascript='standardAlternateFields(\'import_all\',\'import_items\',NULL,false);';
+		$javascript='standardAlternateFields([\'import_all\',\'import_items\'],true);';
 		$fields->attach(form_input_tick(do_lang_tempcode('IMPORT_ALL'),do_lang_tempcode('DESCRIPTION_IMPORT_ALL'),'import_all',true));
 		$fields->attach($importer_object->get_import_items_selector($content_type)); // Returns a form field called import_items
 
diff --git a/adminzone/pages/modules/admin_lang.php b/adminzone/pages/modules/admin_lang.php
index d55865c..4e7e047 100644
--- a/adminzone/pages/modules/admin_lang.php
+++ b/adminzone/pages/modules/admin_lang.php
@@ -110,26 +110,43 @@ class Module_admin_lang
 		$langs=new ocp_tempcode();
 		if ($provide_na) $langs->attach(form_input_list_entry('',false,do_lang_tempcode('NA')));
 		$langs->attach(nice_get_langs(NULL,$add_lang));
-		$fields=form_input_list(do_lang_tempcode('LANGUAGE'),do_lang_tempcode('DESCRIPTION_LANGUAGE'),$param_name,$langs,NULL,false,false);
 
 		$javascript='';
 
+		$fields=new ocp_tempcode();
+
 		if ($add_lang)
 		{
-			$fields->attach(form_input_codename(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('LANGUAGE')),do_lang_tempcode('DESCRIPTION_NEW_LANG'),'lang_new','',false));
-			$javascript.='standardAlternateFields(\'lang\',\'lang_new\');';
+			$set_name='language';
+			$required=true;
+			$set_title=do_lang_tempcode('LANGUAGE');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('DESCRIPTION_LANGUAGE'),$param_name,$langs,NULL,false,false));
+
+			$field_set->attach(form_input_codename(do_lang_tempcode('NEW'),do_lang_tempcode('DESCRIPTION_NEW_LANG'),'lang_new','',false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+		} else
+		{
+			$fields->attach(form_input_list(do_lang_tempcode('LANGUAGE'),do_lang_tempcode('DESCRIPTION_LANGUAGE'),$param_name,$langs,NULL,false,false));
 		}
 
 		if ($choose_lang_file)
 		{
+			$set_name='language_file';
+			$required=true;
+			$set_title=do_lang_tempcode('LANGUAGE_FILE');
+			$field_set=alternate_fields_set__start($set_name);
+
 			$lang_files=new ocp_tempcode();
 			$lang_files->attach(form_input_list_entry('',false,do_lang_tempcode('NA_EM')));
 			$lang_files->attach(nice_get_lang_files());
-			$fields->attach(form_input_list(do_lang_tempcode('LANGUAGE_FILE'),do_lang_tempcode('DESCRIPTION_LANGUAGE_FILE'),'lang_file',$lang_files,NULL,true));
+			$field_set->attach(form_input_list(do_lang_tempcode('CODENAME'),do_lang_tempcode('DESCRIPTION_LANGUAGE_FILE'),'lang_file',$lang_files,NULL,true));
 
-			$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang('SEARCH')),'','search','',false));
+			$field_set->attach(form_input_line(do_lang('SEARCH'),'','search','',false));
 
-			$javascript.='standardAlternateFields(\'lang_file\',\'search\');';
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
 		}
 	
 		$post_url=get_self_url(false,false,NULL,false,true);
diff --git a/adminzone/pages/modules/admin_menus.php b/adminzone/pages/modules/admin_menus.php
index d311fa4..fe66acb 100644
--- a/adminzone/pages/modules/admin_menus.php
+++ b/adminzone/pages/modules/admin_menus.php
@@ -165,22 +165,30 @@ class Module_admin_menus
 	
 		require_code('form_templates');
 		$rows=$GLOBALS['SITE_DB']->query_select('menu_items',array('DISTINCT i_menu'),NULL,'ORDER BY i_menu');
-		$list=form_input_list_entry('',false,do_lang_tempcode('NA_EM'));
+		$list=new ocp_tempcode();//form_input_list_entry('',false,do_lang_tempcode('NA_EM'));
 		foreach ($rows as $row)
 		{
 			$list->attach(form_input_list_entry($row['i_menu']));
 		}
 		$fields=new ocp_tempcode();
-		$fields->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('EXISTING_MENU'),'id',$list,NULL,true,false));
-		$fields->attach(form_input_codename(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('NEW')),do_lang_tempcode('NEW_MENU'),'id_new','',false));
+
+		$set_name='menu';
+		$required=true;
+		$set_title=do_lang_tempcode('MENU');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('EXISTING_MENU'),'id',$list,NULL,true,false));
+
+		$field_set->attach(form_input_codename(do_lang_tempcode('NEW'),do_lang_tempcode('NEW_MENU'),'id_new','',false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		$map=array('page'=>'_SELF','type'=>'edit','wide'=>1);
 		if (get_param('redirect','!')!='!') $map['redirect']=get_param('redirect');
 		$post_url=build_url($map,'_SELF',NULL,false,true);
 		$submit_name=do_lang_tempcode('CHOOSE');
 
-		$javascript='standardAlternateFields(\'id\',\'id_new\');';
-
-		return do_template('FORM_SCREEN',array('_GUID'=>'f3c04ea3fb5e429210c5e33e5a2f2092','GET'=>true,'SKIP_VALIDATION'=>true,'TITLE'=>$title,'HIDDEN'=>'','TEXT'=>do_lang_tempcode('CHOOSE_EDIT_LIST'),'FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name,'JAVASCRIPT'=>$javascript));
+		return do_template('FORM_SCREEN',array('_GUID'=>'f3c04ea3fb5e429210c5e33e5a2f2092','GET'=>true,'SKIP_VALIDATION'=>true,'TITLE'=>$title,'HIDDEN'=>'','TEXT'=>do_lang_tempcode('CHOOSE_EDIT_LIST'),'FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name));
 	}
 
 	/**
diff --git a/adminzone/pages/modules/admin_ocf_emoticons.php b/adminzone/pages/modules/admin_ocf_emoticons.php
index 169341a..c6a46c3 100644
--- a/adminzone/pages/modules/admin_ocf_emoticons.php
+++ b/adminzone/pages/modules/admin_ocf_emoticons.php
@@ -31,7 +31,6 @@ class Module_admin_ocf_emoticons extends standard_aed_module
 	var $array_key='e_code';
 	var $title_is_multi_lang=false;
 	var $non_integer_id=true;
-	var $javascript='standardAlternateFields(\'file\',\'theme_img_code*\');';
 	var $possibly_some_kind_of_upload=true;
 	var $do_preview=NULL;
 	var $menu_label='EMOTICONS';
@@ -334,14 +333,29 @@ class Module_admin_ocf_emoticons extends standard_aed_module
 
 		$fields->attach(form_input_line(do_lang_tempcode('CODE'),do_lang_tempcode('DESCRIPTION_EMOTICON_CODE'),'code',$code,true));
 
+		require_code('themes2');
+		$ids=get_all_image_ids_type('ocf_emoticons',false,$GLOBALS['FORUM_DB']);
+
 		if (get_base_url()==get_forum_base_url())
 		{
-			$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+			$set_name='image';
+			$required=true;
+			$set_title=do_lang_tempcode('IMAGE');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$theme_img_code,NULL,false,$GLOBALS['FORUM_DB']);
+			$field_set->attach($image_chooser_field);
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 			handle_max_file_size($hidden,'image');
+		} else
+		{
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$theme_img_code,NULL,true,$GLOBALS['FORUM_DB']);
+			$fields->attach($image_chooser_field);
 		}
-		require_code('themes2');
-		$ids=get_all_image_ids_type('ocf_emoticons',false,$GLOBALS['FORUM_DB']);
-		$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'theme_img_code',$ids,NULL,$theme_img_code,NULL,true,$GLOBALS['FORUM_DB']));
 
 		$list=new ocp_tempcode();
 		for ($i=0;$i<=4;$i++)
diff --git a/adminzone/pages/modules/admin_ocf_groups.php b/adminzone/pages/modules/admin_ocf_groups.php
index f7e6aeb..0141dce 100644
--- a/adminzone/pages/modules/admin_ocf_groups.php
+++ b/adminzone/pages/modules/admin_ocf_groups.php
@@ -27,7 +27,7 @@ class Module_admin_ocf_groups extends standard_aed_module
 {
 	var $lang_type='GROUP';
 	var $select_name='NAME';
-	var $javascript='standardAlternateFields(\'file\',\'theme_img_code*\',null,true); if (document.getElementById(\'delete\')) { var form=document.getElementById(\'delete\').form; var crf=function() { if (form.elements[\'new_usergroup\']) form.elements[\'new_usergroup\'].disabled=(form.elements[\'delete\'] && !form.elements[\'delete\'].checked); }; crf(); if (form.elements[\'delete\']) form.elements[\'delete\'].onchange=crf; } if (document.getElementById(\'is_presented_at_install\')) { var form=document.getElementById(\'is_presented_at_install\').form; var crf2=function() { if (form.elements[\'is_default\']) form.elements[\'is_default\'].disabled=(form.elements[\'is_presented_at_install\'].checked); if (form.elements[\'is_presented_at_install\'].checked) form.elements[\'is_default\'].checked=false; }; crf2(); form.elements[\'is_presented_at_install\'].onchange=crf2; var crf3=function() { if (form.elements[\'absorb\']) form.elements[\'absorb\'].disabled=(form.elements[\'is_private_club\'] && form.elements[\'is_private_club\'].checked); }; crf3(); if (form.elements[\'is_private_club\']) form.elements[\'is_private_club\'].onchange=crf3; }';
+	var $javascript='if (document.getElementById(\'delete\')) { var form=document.getElementById(\'delete\').form; var crf=function() { if (form.elements[\'new_usergroup\']) form.elements[\'new_usergroup\'].disabled=(form.elements[\'delete\'] && !form.elements[\'delete\'].checked); }; crf(); if (form.elements[\'delete\']) form.elements[\'delete\'].onchange=crf; } if (document.getElementById(\'is_presented_at_install\')) { var form=document.getElementById(\'is_presented_at_install\').form; var crf2=function() { if (form.elements[\'is_default\']) form.elements[\'is_default\'].disabled=(form.elements[\'is_presented_at_install\'].checked); if (form.elements[\'is_presented_at_install\'].checked) form.elements[\'is_default\'].checked=false; }; crf2(); form.elements[\'is_presented_at_install\'].onchange=crf2; var crf3=function() { if (form.elements[\'absorb\']) form.elements[\'absorb\'].disabled=(form.elements[\'is_private_club\'] && form.elements[\'is_private_club\'].checked); }; crf3(); if (form.elements[\'is_private_club\']) form.elements[\'is_private_club\'].onchange=crf3; }';
 	var $award_type='group';
 	var $possibly_some_kind_of_upload=true;
 	var $output_of_action_is_confirmation=true;
@@ -197,14 +197,31 @@ class Module_admin_ocf_groups extends standard_aed_module
 			$fields->attach(form_input_list(do_lang_tempcode('PROMOTION_TARGET'),do_lang_tempcode('DESCRIPTION_PROMOTION_TARGET'),'promotion_target',$promotion_target_groups));
 			$fields->attach(form_input_integer(do_lang_tempcode('PROMOTION_THRESHOLD'),do_lang_tempcode('DESCRIPTION_PROMOTION_THRESHOLD'),'promotion_threshold',$promotion_threshold,false));
 		}
+
+		require_code('themes2');
+		$ids=get_all_image_ids_type('ocf_rank_images',false,$GLOBALS['FORUM_DB']);
+
 		if (get_base_url()==get_forum_base_url())
 		{
+			$set_name='rank_image';
+			$required=false;
+			$set_title=do_lang_tempcode('RANK_IMAGE');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$rank_image,NULL,false,$GLOBALS['FORUM_DB']);
+			$field_set->attach($image_chooser_field);
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_RANK_IMAGE'),$field_set,$required));
+
 			handle_max_file_size($hidden,'image');
-			$fields->attach(form_input_upload(do_lang_tempcode('RANK_IMAGE'),do_lang_tempcode('DESCRIPTION_RANK_IMAGE'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+		} else
+		{
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$rank_image,NULL,true,$GLOBALS['FORUM_DB']);
+			$fields->attach($image_chooser_field);
 		}
-		require_code('themes2');
-		$ids=get_all_image_ids_type('ocf_rank_images',false,$GLOBALS['FORUM_DB']);
-		$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'theme_img_code',$ids,NULL,$rank_image,NULL,true,$GLOBALS['FORUM_DB']));
+
 		$fields->attach(form_input_tick(do_lang_tempcode('RANK_IMAGE_PRI_ONLY'),do_lang_tempcode('RANK_IMAGE_PRI_ONLY_DESCRIPTION'),'rank_image_pri_only',$rank_image_pri_only==1));
 	
 		$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('SECTION_HIDDEN'=>true,'TITLE'=>do_lang_tempcode('BENEFITS'))));
diff --git a/adminzone/pages/modules/admin_themes.php b/adminzone/pages/modules/admin_themes.php
index 9792204..aa6ca04 100644
--- a/adminzone/pages/modules/admin_themes.php
+++ b/adminzone/pages/modules/admin_themes.php
@@ -1095,11 +1095,22 @@ class Module_admin_themes
 			$files.=$temp->evaluate(); // XHTMLXHTML
 		}
 		$fields=new ocp_tempcode();
-		$fields->attach(form_input_multi_list(do_lang_tempcode('EXISTING'),'','f0file',make_string_tempcode($files),NULL,35));
-		$fields->attach(form_input_line(do_lang_tempcode('SEARCH'),do_lang_tempcode('DESCRIPTION_TEMPLATES_SEARCH'),'search','',false));
-		$fields->attach(form_input_codename(do_lang_tempcode('NEW'),do_lang_tempcode('NEW_TEMPLATE'),'f0file2','',false));
+
+		$set_name='template';
+		$required=true;
+		$set_title=do_lang_tempcode('TEMPLATE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_multi_list(do_lang_tempcode('EXISTING'),'','f0file',make_string_tempcode($files),NULL,35));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('SEARCH'),do_lang_tempcode('DESCRIPTION_TEMPLATES_SEARCH'),'search','',false));
+
+		$field_set->attach(form_input_codename(do_lang_tempcode('NEW'),do_lang_tempcode('NEW_TEMPLATE'),'f0file2','',false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		$post_url=build_url(array('page'=>'_SELF','type'=>'_edit_templates','theme'=>$theme),'_SELF');
-		$edit_form=do_template('FORM',array('_GUID'=>'b26747b4a29281baf83b31167c63582a','GET'=>true,'HIDDEN'=>'','TEXT'=>'','URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>do_lang_tempcode('CHOOSE'),'JAVASCRIPT'=>'standardAlternateFields(\'f0file\',\'f0file2\',\'search\');'));
+		$edit_form=do_template('FORM',array('_GUID'=>'b26747b4a29281baf83b31167c63582a','GET'=>true,'HIDDEN'=>'','TEXT'=>'','URL'=>$post_url,'FIELDS'=>$fields,'SUBMIT_NAME'=>do_lang_tempcode('CHOOSE')));
 
 		list($warning_details,$ping_url)=handle_conflict_resolution(''); // Intentionally blank, because only one person should edit any of all templates at any time (because they depend on each other)
 
@@ -1637,9 +1648,19 @@ class Module_admin_themes
 			$list->attach(combo_get_image_paths($path,get_base_url().'/themes/default/images_custom/',get_file_base().'/themes/default/images_custom/'));
 		}*/
 		handle_max_file_size($hidden,'image');
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-	//	$fields->attach(form_input_radio(do_lang_tempcode('CHOOSE'),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),$list));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'path',$path,false));
+
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+	//	$fields->attach(form_input_radio(do_lang_tempcode('CHOOSE'),'',$list));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','path',$path,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		return array($fields,$hidden);
 	}
 
@@ -1675,7 +1696,7 @@ class Module_admin_themes
 			$text->attach(paragraph(do_lang_tempcode(is_null($config_url)?'MAXIMUM_UPLOAD':'MAXIMUM_UPLOAD_STAFF',escape_html(($max>10.0)?integer_format(intval($max)):float_format($max)),escape_html($config_url))));
 		}
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'7b8066b63002cda0a7628ddadddd9962','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'JAVASCRIPT'=>'standardAlternateFields(\'file\',\'path\');'));
+		return do_template('FORM_SCREEN',array('_GUID'=>'7b8066b63002cda0a7628ddadddd9962','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name));
 	}
 
 	/**
@@ -1849,7 +1870,7 @@ class Module_admin_themes
 			$text->attach(paragraph(do_lang_tempcode(is_null($config_url)?'MAXIMUM_UPLOAD':'MAXIMUM_UPLOAD_STAFF',escape_html(($max>10.0)?integer_format(intval($max)):float_format($max)),escape_html($config_url))));
 		}
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'b0e178ad1f840a07c4967f3c266c750b','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'JAVASCRIPT'=>'standardAlternateFields(\'file\',\'path\');'));
+		return do_template('FORM_SCREEN',array('_GUID'=>'b0e178ad1f840a07c4967f3c266c750b','HIDDEN'=>$hidden,'TITLE'=>$title,'URL'=>$post_url,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name));
 	}
 
 	/**
diff --git a/adminzone/pages/modules/admin_zones.php b/adminzone/pages/modules/admin_zones.php
index 5d24e80..92429a6 100644
--- a/adminzone/pages/modules/admin_zones.php
+++ b/adminzone/pages/modules/admin_zones.php
@@ -492,7 +492,12 @@ class Module_admin_zones
 			{
 				$fields.=static_evaluate_tempcode(do_template('FORM_SCREEN_FIELD_SPACER',array('SECTION_HIDDEN'=>true,'TITLE'=>do_lang_tempcode('THEME_LOGO',escape_html($theme_name)))));
 
-				$fields.=static_evaluate_tempcode(form_input_upload(do_lang_tempcode('IMAGE'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'logo_upload_'.$theme,false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+				$set_name='image';
+				$required=true;
+				$set_title=do_lang_tempcode('LOGO');
+				$field_set=alternate_fields_set__start($set_name);
+
+				$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','logo_upload_'.$theme,false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
 				require_code('themes2');
 				$ids=get_all_image_ids_type('logo',false,NULL,$theme);
 				$current_logo='logo/'.$zone.'-logo';
@@ -504,9 +509,9 @@ class Module_admin_zones
 					if ($test=='') $test=find_theme_image($id,false,false,'default');
 					if (($test=='') && ($id==$current_logo)) $current_logo=$ids[0];
 				}
-				$fields.=static_evaluate_tempcode(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'logo_select_'.$theme,$ids,NULL,$current_logo,NULL,true,NULL,$theme));
+				$field_set->attach(form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','logo_select_'.$theme,$ids,NULL,$current_logo,NULL,false,NULL,$theme));
 
-				$javascript.='standardAlternateFields(\'logo_upload_'.$theme.'\',\'logo_select_'.$theme.'*\');';
+				$fields.=static_evaluate_tempcode(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
 			}
 		}
 
diff --git a/adminzone/pages/modules_custom/admin_ocdeadpeople.php b/adminzone/pages/modules_custom/admin_ocdeadpeople.php
index ec24695..288480c 100644
--- a/adminzone/pages/modules_custom/admin_ocdeadpeople.php
+++ b/adminzone/pages/modules_custom/admin_ocdeadpeople.php
@@ -206,8 +206,17 @@ class Module_admin_ocdeadpeople extends standard_aed_module
 
 		$fields->attach(form_input_line(do_lang_tempcode('DISEASE'),do_lang_tempcode('DESCRIPTION_DISEASE'),'name',$name,true));
 
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'image',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$image,false));
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','image',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$image,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		handle_max_file_size($hidden,'image');
 
 		$fields->attach(form_input_line(do_lang_tempcode('CURE'),do_lang_tempcode('DESCRIPTION_CURE'),'cure',$cure,true));
diff --git a/adminzone/pages/modules_custom/admin_ocgifts.php b/adminzone/pages/modules_custom/admin_ocgifts.php
index 7a137f0..31695ee 100644
--- a/adminzone/pages/modules_custom/admin_ocgifts.php
+++ b/adminzone/pages/modules_custom/admin_ocgifts.php
@@ -28,7 +28,6 @@ class Module_admin_ocgifts extends standard_aed_module
 	var $menu_label='OCGIFTS_TITLE';
 	var $do_preview=NULL;
 	var $view_entry_point='_SEARCH:admin_ocgifts:view:id=_ID';
-	var $javascript='standardAlternateFields(\'image\',\'url\');';
 
 	/**
 	 * Standard modular info function.
@@ -228,10 +227,18 @@ class Module_admin_ocgifts extends standard_aed_module
 
 		$fields->attach(form_input_line(do_lang_tempcode('CATEGORY'),do_lang_tempcode('DESCRIPTION_GIFT_CATEGORY'),'category',$category,true));
 
-		$fields->attach(form_input_upload(do_lang_tempcode('IMAGE'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'image',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$image,false));
-		handle_max_file_size($hidden,'image');
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','image',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$image,false));
 
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
+		handle_max_file_size($hidden,'image');
 
 		$fields->attach(form_input_line(do_lang_tempcode('PRICE'),'','price',strval($price),true));
 
diff --git a/cms/pages/modules/cms_banners.php b/cms/pages/modules/cms_banners.php
index 05cecc0..a8195ca 100644
--- a/cms/pages/modules/cms_banners.php
+++ b/cms/pages/modules/cms_banners.php
@@ -34,7 +34,7 @@ class Module_cms_banners extends standard_aed_module
 	var $upload='image';
 	var $non_integer_id=true;
 	var $permission_module='banners';
-	var $javascript='standardAlternateFields(\'file\',\'image_url\',null,true); var form=document.getElementById(\'campaignremaining\').form; var crf=function() { form.elements[\'campaignremaining\'].disabled=(!form.elements[\'the_type\'][1].checked); }; crf(); form.elements[\'the_type\'][0].onclick=crf; form.elements[\'the_type\'][1].onclick=crf; form.elements[\'the_type\'][2].onclick=crf;';
+	var $javascript='var form=document.getElementById(\'campaignremaining\').form; var crf=function() { form.elements[\'campaignremaining\'].disabled=(!form.elements[\'the_type\'][1].checked); }; crf(); form.elements[\'the_type\'][0].onclick=crf; form.elements[\'the_type\'][1].onclick=crf; form.elements[\'the_type\'][2].onclick=crf;';
 	var $menu_label='BANNERS';
 	var $array_key='name';
 
diff --git a/cms/pages/modules/cms_blogs.php b/cms/pages/modules/cms_blogs.php
index c3626d2..3a55414 100644
--- a/cms/pages/modules/cms_blogs.php
+++ b/cms/pages/modules/cms_blogs.php
@@ -549,17 +549,22 @@ class Module_cms_blogs extends standard_aed_module
 		// Build up form
 		$fields_xml=new ocp_tempcode();		
 
-		$fields_xml->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_WP_XML'),'file_novalidate',false,NULL,NULL,true,'xml'));
+		$set_name='rss';
+		$required=true;
+		$set_title=do_lang_tempcode('FILE');
+		$field_set=alternate_fields_set__start($set_name);
 
-		$fields_xml->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'xml_url','',false));
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file_novalidate',false,NULL,NULL,true,'xml'));
 
-		$hidden=form_input_hidden('lang',$lang);
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','xml_url','',false));
+
+		$fields_xml->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_WP_XML'),$field_set,$required));
 
-		$javascript='standardAlternateFields(\'file_novalidate\',\'xml_url\');';
+		$hidden=form_input_hidden('lang',$lang);
 
 		$xml_post_url	=	build_url(array('page'=>'_SELF','type'=>'_import_wordpress','method'=>'xml'),'_SELF');
 
-		$xml_upload_form	=	do_template('FORM',array('TABINDEX'=>strval(get_form_field_tabindex()),'TEXT'=>'','HIDDEN'=>$hidden,'FIELDS'=>$fields_xml,'SUBMIT_NAME'=>$submit_name,'URL'=>$xml_post_url,'JAVASCRIPT'=>$javascript));
+		$xml_upload_form	=	do_template('FORM',array('TABINDEX'=>strval(get_form_field_tabindex()),'TEXT'=>'','HIDDEN'=>$hidden,'FIELDS'=>$fields_xml,'SUBMIT_NAME'=>$submit_name,'URL'=>$xml_post_url));
 
 		//--------------------------------------------
 		$fields=new ocp_tempcode();	
diff --git a/cms/pages/modules/cms_calendar.php b/cms/pages/modules/cms_calendar.php
index 0941e68..4f5d023 100644
--- a/cms/pages/modules/cms_calendar.php
+++ b/cms/pages/modules/cms_calendar.php
@@ -987,7 +987,6 @@ class Module_cms_calendar_cat extends standard_aed_module
 	var $table='calendar_types';
 	var $permissions_require='cat_high';
 	var $permission_module='calendar';
-	var $javascript='standardAlternateFields(\'file\',\'theme_img_code*\');';
 	var $menu_label='CALENDAR';
 
 	/**
@@ -1008,8 +1007,18 @@ class Module_cms_calendar_cat extends standard_aed_module
 
 		require_code('themes2');
 		$ids=get_all_image_ids_type('calendar');
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'theme_img_code',$ids,NULL,$logo,NULL,true));
+
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$logo,NULL,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		handle_max_file_size($hidden,'image');
 
 		if (addon_installed('syndication_blocks'))
diff --git a/cms/pages/modules/cms_downloads.php b/cms/pages/modules/cms_downloads.php
index 29304f3..b2b7793 100644
--- a/cms/pages/modules/cms_downloads.php
+++ b/cms/pages/modules/cms_downloads.php
@@ -33,7 +33,7 @@ class Module_cms_downloads extends standard_aed_module
 	var $user_facing=true;
 	var $seo_type='downloads_download';
 	var $upload='file';
-	var $javascript='standardAlternateFields(\'file\',\'url\'); var url=document.getElementById(\'url\'); var form=url.form; var crf=function() { var s=url.value!=\'\'; if (form.elements[\'copy_to_server\']) form.elements[\'copy_to_server\'].disabled=!s; if (form.elements[\'file_size\']) form.elements[\'file_size\'].disabled=!s; }; crf(); url.onchange=crf; url.onkeyup=crf; var cost=document.getElementById(\'cost\'); if (cost) { var form=cost.form; var crf2=function() { var s=(cost.value!=\'\') && (cost.value!=\'0\'); if (form.elements[\'submitter_gets_points\']) form.elements[\'submitter_gets_points\'].disabled=!s; }; crf2(); cost.onchange=crf2; cost.onkeyup=crf2; }';
+	var $javascript='var url=document.getElementById(\'url\'); var form=url.form; var crf=function() { var s=url.value!=\'\'; if (form.elements[\'copy_to_server\']) form.elements[\'copy_to_server\'].disabled=!s; if (form.elements[\'file_size\']) form.elements[\'file_size\'].disabled=!s; }; crf(); url.onchange=crf; url.onkeyup=crf; var cost=document.getElementById(\'cost\'); if (cost) { var form=cost.form; var crf2=function() { var s=(cost.value!=\'\') && (cost.value!=\'0\'); if (form.elements[\'submitter_gets_points\']) form.elements[\'submitter_gets_points\'].disabled=!s; }; crf2(); cost.onchange=crf2; cost.onkeyup=crf2; }';
 	var $award_type='download';
 	var $menu_label='SECTION_DOWNLOADS';
 	var $table='download_downloads';
@@ -484,8 +484,18 @@ class Module_cms_downloads extends standard_aed_module
 		$fields->attach(form_input_line(do_lang_tempcode('NAME'),do_lang_tempcode('DESCRIPTION_NAME'),'name',$name,true));
 		if (!is_null($original_filename)) $fields->attach(form_input_line(do_lang_tempcode('ORIGINAL_FILENAME'),do_lang_tempcode('DESCRIPTION_ORIGINAL_FILENAME'),'original_filename',$original_filename,false));
 		$fields->attach(form_input_tree_list(do_lang_tempcode('CATEGORY'),do_lang_tempcode('DESCRIPTION_CATEGORY_TREE'),'category_id',NULL,'choose_download_category',array(),true,strval(is_null($category_id)?db_get_first_id():$category_id)));
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$url,false));
+
+		$set_name='file';
+		$required=true;
+		$set_title=do_lang_tempcode('FILE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		if (has_specific_permission(get_member(),'draw_to_server'))
 			$fields->attach(form_input_tick(do_lang_tempcode('COPY_TO_SERVER'),do_lang_tempcode('DESCRIPTION_COPY_TO_SERVER'),'copy_to_server',false));
 		$fields->attach(form_input_integer(do_lang_tempcode('_FILE_SIZE'),do_lang_tempcode('DESCRIPTION_FILE_SIZE'),'file_size',$file_size,false));
diff --git a/cms/pages/modules/cms_galleries.php b/cms/pages/modules/cms_galleries.php
index bd9630f..b9b2c47 100644
--- a/cms/pages/modules/cms_galleries.php
+++ b/cms/pages/modules/cms_galleries.php
@@ -35,7 +35,6 @@ class Module_cms_galleries extends standard_aed_module
 	var $seo_type='image';
 	var $upload='image';
 	var $award_type='image';
-	var $javascript='standardAlternateFields(\'file\',\'url\'); standardAlternateFields(\'file2\',\'thumb_url\');';
 	var $menu_label='GALLERIES';
 	var $table='images';
 
@@ -202,11 +201,14 @@ class Module_cms_galleries extends standard_aed_module
 		}
 		$post_url=build_url(array('page'=>'_SELF','type'=>'_gimp'),'_SELF',NULL,false,true);
 		require_code('form_templates');
+
 		$fields=new ocp_tempcode();
+
 		$fields->attach(form_input_tree_list(do_lang_tempcode('GALLERY'),'','name',NULL,'choose_gallery',array('purity'=>false,'filter'=>$condition,'member_id'=>$member_id),true,''));
+
 		$submit_name=do_lang_tempcode('GALLERY_IMPORT');
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'5213edb75c8d534c121b587c555a3b9a','TITLE'=>$title,'SKIP_VALIDATION'=>true,'GET'=>true,'HIDDEN'=>'','TEXT'=>'','FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name,'JAVASCRIPT'=>'standardAlternateFields(\'name\',\'name2\');'));
+		return do_template('FORM_SCREEN',array('_GUID'=>'5213edb75c8d534c121b587c555a3b9a','TITLE'=>$title,'SKIP_VALIDATION'=>true,'GET'=>true,'HIDDEN'=>'','TEXT'=>'','FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name));
 	}
 
 	/**
@@ -889,13 +891,32 @@ class Module_cms_galleries extends standard_aed_module
 		$fields->attach(form_input_line(do_lang_tempcode('TITLE',do_lang_tempcode('TITLE')),do_lang_tempcode('DESCRIPTION_TITLE'),'title',$title,false));
 
 		$fields->attach(form_input_tree_list(do_lang_tempcode('GALLERY'),do_lang_tempcode('DESCRIPTION_GALLERY'),'cat',NULL,'choose_gallery',$filters,true,$cat));
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$url,false));
+
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		if (get_option('is_on_gd')=='0')
 		{
 			$thumb_width=get_option('thumb_width');
-			$fields->attach(form_input_upload(do_lang_tempcode('THUMBNAIL'),do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),'file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-			$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'thumb_url',$thumb_url,false));
+
+			$set_name='thumbnail';
+			$required=true;
+			$set_title=do_lang_tempcode('THUMBNAIL');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','thumb_url',$thumb_url,false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),$field_set,$required));
 		}
 		$fields->attach(form_input_text_comcode(do_lang_tempcode('DESCRIPTION'),do_lang_tempcode('DESCRIPTION_DESCRIPTION_ACCESSIBILITY'),'comments',$comments,false));
 		if ($validated==0)
@@ -1130,7 +1151,7 @@ class Module_cms_galleries_alt extends standard_aed_module
 	var $user_facing=true;
 	var $seo_type='video';
 	var $upload='file';
-	var $javascript='standardAlternateFields(\'file\',\'url\'); standardAlternateFields(\'file2\',\'thumb_url\');';
+	var $javascript='';
 	var $award_type='video';
 	var $menu_label='GALLERIES';
 	var $table='videos';
@@ -1267,10 +1288,6 @@ class Module_cms_galleries_alt extends standard_aed_module
 		list($allow_rating,$allow_comments,$allow_trackbacks)=$this->choose_feedback_fields_statistically($allow_rating,$allow_comments,$allow_trackbacks);
 
 		$no_thumb_needed=(get_option('ffmpeg_path')!='') || (class_exists('ffmpeg_movie'));
-		if (!$no_thumb_needed)
-			$this->javascript='standardAlternateFields(\'file\',\'url\'); standardAlternateFields(\'file2\',\'thumb_url\',null,true);';
-		else
-			$this->javascript='standardAlternateFields(\'file\',\'url\');';
 
 		if ($cat=='')
 		{
@@ -1286,8 +1303,18 @@ class Module_cms_galleries_alt extends standard_aed_module
 
 		$fields->attach(form_input_tree_list(do_lang_tempcode('GALLERY'),do_lang_tempcode('DESCRIPTION_GALLERY'),'cat',NULL,'choose_gallery',array('filter'=>'only_conventional_galleries','must_accept_videos'=>true,'addable_filter'=>true),true,$cat));
 		$supported=get_allowed_video_file_types();
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,$supported));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$url,false));
+
+		$set_name='video';
+		$required=true;
+		$set_title=do_lang_tempcode('VIDEO');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,$supported));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		if ($validated==0)
 		{
 			$validated=get_param_integer('validated',0);
@@ -1306,8 +1333,18 @@ class Module_cms_galleries_alt extends standard_aed_module
 			$temp=do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ADVANCED'),'SECTION_HIDDEN'=>true));
 			$fields->attach($temp);
 		}
-		$fields->attach(form_input_upload(do_lang_tempcode('THUMBNAIL'),do_lang_tempcode('_DESCRIPTION_THUMBNAIL',integer_format($thumb_width)),'file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'thumb_url',$thumb_url,false));
+
+		$set_name='thumbnail';
+		$required=true;
+		$set_title=do_lang_tempcode('THUMBNAIL');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','thumb_url',$thumb_url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('_DESCRIPTION_THUMBNAIL',integer_format($thumb_width)),$field_set,$required));
+
 		if (!$no_thumb_needed)
 		{
 			$fields->attach($description_field);
diff --git a/cms/pages/modules/cms_iotds.php b/cms/pages/modules/cms_iotds.php
index 3764d04..a22a5be 100644
--- a/cms/pages/modules/cms_iotds.php
+++ b/cms/pages/modules/cms_iotds.php
@@ -33,7 +33,6 @@ class Module_cms_iotds extends standard_aed_module
 	var $send_validation_request=false;
 	var $upload='image';
 	var $permissions_require='mid';
-	var $javascript='standardAlternateFields(\'file\',\'url\'); standardAlternateFields(\'file2\',\'thumb_url\');';
 	var $menu_label='IOTDS';
 	var $table='iotd';
 
@@ -130,13 +129,32 @@ class Module_cms_iotds extends standard_aed_module
 		require_code('form_templates');
 		handle_max_file_size($hidden,'image');
 		$fields->attach(form_input_line_comcode(do_lang_tempcode('TITLE'),do_lang_tempcode('DESCRIPTION_TITLE'),'title',$title,true));
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'url',$url,false));
+
+		$set_name='image';
+		$required=true;
+		$set_title=do_lang_tempcode('IMAGE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','url',$url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		if (get_option('is_on_gd')=='0')
 		{
 			$thumb_width=get_option('thumb_width');
-			$fields->attach(form_input_upload(do_lang_tempcode('THUMBNAIL'),do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),'file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-			$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'thumb_url',$thumb_url,false));
+
+			$set_name='thumbnail';
+			$required=true;
+			$set_title=do_lang_tempcode('THUMBNAIL');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','thumb_url',$thumb_url,false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),$field_set,$required));
 		}
 		$fields->attach(form_input_text_comcode(do_lang_tempcode('CAPTION'),do_lang_tempcode('DESCRIPTION_DESCRIPTION'),'caption',$caption,false));
 		if (has_specific_permission(get_member(),'choose_iotd'))
diff --git a/cms/pages/modules/cms_news.php b/cms/pages/modules/cms_news.php
index 76d95c6..cb5d55d 100644
--- a/cms/pages/modules/cms_news.php
+++ b/cms/pages/modules/cms_news.php
@@ -574,10 +574,17 @@ class Module_cms_news extends standard_aed_module
 		// Build up form
 		$fields=new ocp_tempcode();
 		require_code('form_templates');
-	
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_RSS_FEED'),'file_novalidate',false,NULL,NULL,true,'rss,xml,atom'));
 
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'rss_feed_url','',false));
+		$set_name='rss_file';
+		$required=true;
+		$set_title=do_lang_tempcode('FILE');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','file_novalidate',false,NULL,NULL,true,'rss,xml,atom'));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','rss_feed_url','',false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_RSS_FEED'),$field_set,$required));
 
 		$fields->attach(form_input_tick(do_lang_tempcode('AUTO_VALIDATE_ALL_POSTS'),do_lang_tempcode('DESCRIPTION_VALIDATE_ALL_POSTS'),'auto_validate',true));
 		$fields->attach(form_input_tick(do_lang_tempcode('DOWNLOAD_IMAGES'),do_lang_tempcode('DESCRIPTION_DOWNLOAD_IMAGES'),'download_images',true));
@@ -808,7 +815,6 @@ class Module_cms_news_cat extends standard_aed_module
 	var $select_name='TITLE';
 	var $permissions_require='cat_high';
 	var $permission_module='news';
-	var $javascript='standardAlternateFields(\'file\',\'theme_img_code*\');';
 	var $menu_label='NEWS';
 	var $table='news_categories';
 	var $orderer='nc_title';
@@ -891,14 +897,29 @@ class Module_cms_news_cat extends standard_aed_module
 		require_code('form_templates');
 		$fields->attach(form_input_line_comcode(do_lang_tempcode('TITLE'),do_lang_tempcode('DESCRIPTION_TITLE'),'title',$title,true));
 
+		require_code('themes2');
+		$ids=get_all_image_ids_type('newscats');
+
 		if (get_base_url()==get_forum_base_url())
 		{
-			$fields->attach(form_input_upload(do_lang_tempcode('IMAGE'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+			$set_name='rep_image';
+			$required=false;
+			$set_title=do_lang_tempcode('IMAGE');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$img,NULL,false);
+			$field_set->attach($image_chooser_field);
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 			handle_max_file_size($hidden,'image');
+		} else
+		{
+			$image_chooser_field=form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','theme_img_code',$ids,NULL,$img,NULL,true);
+			$fields->attach($image_chooser_field);
 		}
-		require_code('themes2');
-		$ids=get_all_image_ids_type('newscats');
-		$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'theme_img_code',$ids,NULL,$img,NULL,true));
 
 		if (!is_null($owner))
 		{
@@ -948,7 +969,7 @@ class Module_cms_news_cat extends standard_aed_module
 		require_code('themes2');
 		
 		$title=post_param('title');
-		$img=get_theme_img_code('newscats');
+		$img=get_theme_img_code('newscats',true);
 		$notes=post_param('notes','');
 	
 		$id=add_news_category($title,$img,$notes);
@@ -967,7 +988,8 @@ class Module_cms_news_cat extends standard_aed_module
 		require_code('themes2');
 		
 		$title=post_param('title');
-		$img=get_theme_img_code('newscats',STRING_MAGIC_NULL);
+		$img=get_theme_img_code('newscats',true);
+		if (fractional_edit()) $img=STRING_MAGIC_NULL;
 		$notes=post_param('notes',STRING_MAGIC_NULL);
 		$_owner=post_param('owner',fractional_edit()?STRING_MAGIC_NULL:NULL);
 		$owner=is_null($_owner)?NULL:$GLOBALS['FORUM_DRIVER']->get_member_from_username($_owner);
diff --git a/forum/pages/modules/topics.php b/forum/pages/modules/topics.php
index 23a0a5d..8d58619 100644
--- a/forum/pages/modules/topics.php
+++ b/forum/pages/modules/topics.php
@@ -391,8 +391,18 @@ class Module_topics
 		// Certain aspects relating to the posting system
 		$fields=new ocp_tempcode();
 		$hidden=$this->keep_markers();
-		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_TOPIC'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
-		$fields->attach(form_input_integer(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('DESTINATION_TOPIC_ID')),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'manual_topic_id',NULL,false));
+
+		$set_name='destination';
+		$required=true;
+		$set_title=do_lang_tempcode('DESTINATION_TOPIC');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_tree_list(do_lang_tempcode('CHOOSE'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
+
+		$field_set->attach(form_input_integer(do_lang_tempcode('DESTINATION_TOPIC_ID'),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'manual_topic_id',NULL,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		$fields->attach(form_input_tick(do_lang_tempcode('DELETE_IF_EMPTY'),do_lang_tempcode('DESCRIPTION_DELETE_IF_EMPTY'),'delete_if_empty',true));
 		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));
 
@@ -400,7 +410,7 @@ class Module_topics
 		$submit_name=do_lang_tempcode('MOVE_POSTS');
 		$text=do_lang_tempcode('MOVE_POSTS_A_TEXT');
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'d62d2c81583398f26f900ee3df1894b1','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url,'JAVASCRIPT'=>'standardAlternateFields(\'select_topic_id\',\'manual_topic_id\');'));
+		return do_template('FORM_SCREEN',array('_GUID'=>'d62d2c81583398f26f900ee3df1894b1','STAFF_HELP_URL'=>brand_base_url().'/docs'.strval(ocp_version()).'/pg/tut_mod','HIDDEN'=>$hidden,'TITLE'=>$title,'FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
 	}
 
 	/**
@@ -993,8 +1003,18 @@ class Module_topics
 			$filter_cat_text=($filter_cat=='')?do_lang_tempcode('NONE_EM'):make_string_tempcode($filter_cat);
 			$list->attach(form_input_list_entry($filter_cat,$filter_cat=='',$filter_cat_text));
 		}
-		$fields->attach(form_input_list(do_lang_tempcode('CATEGORY'),do_lang_tempcode('DESCRIPTION_CATEGORY'),'category_a',$list,NULL,true));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('NEW')),do_lang_tempcode('DESCRIPTION_ALTERNATE',protect_from_escaping(strtolower(do_lang('CATEGORY')))),'category_b','',false));
+
+		$set_name='category';
+		$required=true;
+		$set_title=do_lang_tempcode('CATEGORY');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_list(do_lang_tempcode('EXISTING'),'','category_a',$list,NULL,true));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('NEW'),'','category_b','',false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_CATEGORY'),$field_set,$required));
+
 		$hidden=$this->keep_markers();
 
 		breadcrumb_set_parents(array(array('_SEARCH:forumview:pt',do_lang_tempcode('PERSONAL_TOPICS'))));
@@ -2904,8 +2924,18 @@ END;
 		$hidden=new ocp_tempcode();
 		$hidden->attach(build_keep_post_fields());
 		$hidden->attach(build_keep_form_fields());
-		$fields->attach(form_input_tree_list(do_lang_tempcode('DESTINATION_TOPIC'),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'select_topic_id',NULL,'choose_forum_topic',array(),false));
-		$fields->attach(form_input_integer(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('DESTINATION_TOPIC_ID')),do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),'manual_topic_id',NULL,false));
+
+		$set_name='destination';
+		$required=true;
+		$set_title=do_lang_tempcode('DESTINATION_TOPIC');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_tree_list(do_lang_tempcode('CHOOSE'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
+
+		$field_set->attach(form_input_integer(do_lang_tempcode('DESTINATION_TOPIC_ID'),'','manual_topic_id',NULL,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_DESTINATION_TOPIC'),$field_set,$required));
+
 		$fields->attach(form_input_line(do_lang_tempcode('REASON'),do_lang_tempcode('DESCRIPTION_REASON'),'reason','',false));
 
 		$topic_title=$GLOBALS['FORUM_DB']->query_value('f_topics','t_cache_first_title',array('id'=>$topic_id));
diff --git a/lang/EN/bookmarks.ini b/lang/EN/bookmarks.ini
index f28d2ce..6c50f43 100755
--- a/lang/EN/bookmarks.ini
+++ b/lang/EN/bookmarks.ini
@@ -2,8 +2,6 @@
 MANAGE_BOOKMARKS=Manage bookmarks
 ADD_BOOKMARK=Add bookmark
 EDIT_BOOKMARK=Edit bookmark
-OLD_BOOKMARK_FOLDER=Existing folder
-NEW_BOOKMARK_FOLDER=New folder
 BOOKMARK_FOLDER=Folder
 DESCRIPTION_OLD_BOOKMARK_FOLDER=You may select one of the existing folders that you are already using.
 DESCRIPTION_NEW_BOOKMARK_FOLDER=Or you may type in the name for a new folder that you'd like to create for this.
diff --git a/lang/EN/global.ini b/lang/EN/global.ini
index e5e37eb..f3e67bd 100644
--- a/lang/EN/global.ini
+++ b/lang/EN/global.ini
@@ -492,9 +492,7 @@ FEEDBACK_THANKYOU=Thank you for your feedback.
 ORGANISATION=Organisation
 DESCRIPTION_CATEGORY_TREE=The position in the category tree in which this belongs.
 DESCRIPTION_ALTERNATE_URL=If you want to supply an existing URL instead of uploading.
-DESCRIPTION_ALTERNATE=If you want to supply a new {1} instead of selecting from existing ones.
 STOCK=Stock
-DESCRIPTION_ALTERNATE_STOCK=If you want to choose a stock one instead of your own. Click the "/" to unselect if you wish to upload instead.
 DESCRIPTION_UPLOAD=If you want to upload a file from your computer.
 _DESCRIPTION_UPLOAD=The file to be uploaded.
 NOT_LOGGED_IN_NO_CREDIT=You are not logged in. If you <a onclick="return open_link_as_overlay(this);" accesskey="l" href="{1}">log in</a>, you will receive point credit for your submission.
diff --git a/lang/EN/menus.ini b/lang/EN/menus.ini
index eb5714f..c4d3494 100644
--- a/lang/EN/menus.ini
+++ b/lang/EN/menus.ini
@@ -51,7 +51,7 @@ DONATE=Donate
 DELETE_ACCOUNT=Delete account
 GUIDE=Guide
 EXISTING_MENU=Choose a menu to edit which already exists.
-NEW_MENU=Or if N/A chosen, enter the name of a new menu here.
+NEW_MENU=Enter the name of a new menu here.
 DOC_CMS=The Content Management Zone is the place to manage most of the categories and entries on the system.\n\nA rough definition of what is considered content is anything you might expect to be readily added on-the-fly. Some forms of content are designed to be added from the main website (for example, comments and forum posts), so are not presented here.
 PHP_INFO=PHP info
 STRUCTURE=Structure
diff --git a/lang_custom/EN/ocdeadpeople.ini b/lang_custom/EN/ocdeadpeople.ini
index cb8e8b0..04d96ed 100644
--- a/lang_custom/EN/ocdeadpeople.ini
+++ b/lang_custom/EN/ocdeadpeople.ini
@@ -18,9 +18,6 @@ DESCRIPTION_POINTS_PER_SPREAD=How many points will be taken from each of the sic
 DISEASE_ENABLED=Enabled
 DISEASE_DISABLED=Disabled
 DESCRIPTION_DISEASE_ENABLED=Enable or disable the disease.
-ALT_FIELD=&nbsp;&nbsp;&nbsp;&raquo; {1}
-DESCRIPTION_ALTERNATE_URL=If you want to supply an existing URL instead of uploading.
-URL=URL
 MANAGE_DISEASES=Manage diseases
 VIEW_DISEASE=View disease
 DISEASES_TITLE=Diseases
diff --git a/lang_custom/EN/ocgifts.ini b/lang_custom/EN/ocgifts.ini
index 74c9d8d..86d5129 100644
--- a/lang_custom/EN/ocgifts.ini
+++ b/lang_custom/EN/ocgifts.ini
@@ -10,9 +10,6 @@ DESCRIPTION_GIFT_ENABLED=Enable or disable the gift.
 VIEW_GIFT=View gift
 GIFT=Gift
 DESCRIPTION_GIFT=Gift name.
-ALT_FIELD=&nbsp;&nbsp;&nbsp;&raquo; {1}
-DESCRIPTION_ALTERNATE_URL=If you want to supply an existing URL instead of uploading.
-URL=URL
 PRICE=Gift price
 ADD_MANAGE_GIFTS=Add Gift
 EDIT_MANAGE_GIFTS=Edit Gift
diff --git a/pages/modules/lostpassword.php b/pages/modules/lostpassword.php
index 20d4e51..135b9ef 100755
--- a/pages/modules/lostpassword.php
+++ b/pages/modules/lostpassword.php
@@ -80,15 +80,25 @@ class Module_lostpassword
 	
 		$fields=new ocp_tempcode();
 		require_code('form_templates');
-		$fields->attach(form_input_username(do_lang_tempcode('USERNAME'),'','username',trim(get_param('username','')),false));
-		$fields->attach(form_input_email(do_lang_tempcode('EMAIL_ADDRESS'),'','email_address',trim(get_param('email_address','')),false));
+
+		$set_name='account';
+		$required=true;
+		$set_title=do_lang_tempcode('ACCOUNT');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_username(do_lang_tempcode('USERNAME'),'','username',trim(get_param('username','')),false));
+
+		$field_set->attach(form_input_email(do_lang_tempcode('EMAIL_ADDRESS'),'','email_address',trim(get_param('email_address','')),false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		$text=do_lang_tempcode('_PASSWORD_RESET_TEXT');
 		$submit_name=do_lang_tempcode('PROCEED');
 		$post_url=build_url(array('page'=>'_SELF','type'=>'step2'),'_SELF');
 
 		breadcrumb_set_self(do_lang_tempcode('RESET_PASSWORD'));
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'080e516fef7c928dbb9fb85beb6e435a','SKIP_VALIDATION'=>true,'JAVASCRIPT'=>'standardAlternateFields(\'username\',\'email_address\');','TITLE'=>$title,'HIDDEN'=>'','FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
+		return do_template('FORM_SCREEN',array('_GUID'=>'080e516fef7c928dbb9fb85beb6e435a','SKIP_VALIDATION'=>true,'TITLE'=>$title,'HIDDEN'=>'','FIELDS'=>$fields,'TEXT'=>$text,'SUBMIT_NAME'=>$submit_name,'URL'=>$post_url));
 	}
 
 	/**
diff --git a/pages/modules/recommend.php b/pages/modules/recommend.php
index 4f6f88d..3579ce6 100644
--- a/pages/modules/recommend.php
+++ b/pages/modules/recommend.php
@@ -144,13 +144,36 @@ class Module_recommend
 
 			$already[]=$email_address;
 		}
+
 		if (is_guest())
 		{
 			$fields->attach(form_input_email(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'),'','email_address_0',array_key_exists(0,$already)?$already[0]:'',true));
 		} else
 		{
-			$fields->attach(form_input_line_multi(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'),do_lang_tempcode('THEIR_ADDRESS'),'email_address_',$already,1,NULL,'email'));
+			if (get_value('disable_csv_recommend')!=='1')
+			{
+				$set_name='people';
+				$required=true;
+				$set_title=do_lang_tempcode('TO');
+				$field_set=alternate_fields_set__start($set_name);
+
+				$email_address_field=form_input_line_multi(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'),do_lang_tempcode('THEIR_ADDRESS'),'email_address_',$already,1,NULL,'email');
+				$field_set->attach($email_address_field);
+
+				//add an upload CSV contacts file field
+				$_help_url=build_url(array('page'=>'recommend_help'),get_page_zone('recommend_help'));
+				$help_url=$_help_url->evaluate();
+
+				$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD_CSV_FILE',escape_html($help_url)),'upload',false,NULL,NULL,false));
+
+				$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+			} else
+			{
+				$email_address_field=form_input_line_multi(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'),do_lang_tempcode('THEIR_ADDRESS'),'email_address_',$already,1,NULL,'email');
+				$fields->attach($email_address_field);
+			}
 		}
+
 		if ((get_option('is_on_invites')=='1') && (get_forum_type()=='ocf') && (!is_guest()))
 		{
 			$invites=get_num_invites(get_member());
@@ -230,11 +253,6 @@ class Module_recommend
 			$need_message=false;
 		}
 
-		//add an upload CSV contacts file field
-		$_help_url=build_url(array('page'=>'recommend_help'),get_page_zone('recommend_help'));
-		$help_url=$_help_url->evaluate();
-		if ((get_value('disable_csv_recommend')!=='1') && (!is_guest()))
-			$fields->attach(form_input_upload(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('UPLOAD')),do_lang_tempcode('DESCRIPTION_UPLOAD_CSV_FILE',escape_html($help_url)),'upload',false,NULL,NULL,false));
 		handle_max_file_size($hidden);
 
 		$fields->attach(form_input_line(do_lang_tempcode('SUBJECT'),'','subject',$subject,true));
@@ -253,11 +271,7 @@ class Module_recommend
 
 		$hidden->attach(form_input_hidden('comcode__message','1'));
 
-		if ((get_value('disable_csv_recommend')!=='1') && (!is_guest()))
-			$javascript='standardAlternateFields(\'upload\',\'email_address_0\');';
-		else $javascript='';
-
-		$javascript.=(function_exists('captcha_ajax_check')?captcha_ajax_check():'');
+		$javascript=(function_exists('captcha_ajax_check')?captcha_ajax_check():'');
 
 		return do_template('FORM_SCREEN',array('_GUID'=>'08a538ca8d78597b0417f464758a59fd','JAVASCRIPT'=>$javascript,'SKIP_VALIDATION'=>true,'TITLE'=>$title,'HIDDEN'=>$hidden,'FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name,'TEXT'=>$text));
 	}
diff --git a/site/pages/modules/bookmarks.php b/site/pages/modules/bookmarks.php
index 12656e9..7d87225 100755
--- a/site/pages/modules/bookmarks.php
+++ b/site/pages/modules/bookmarks.php
@@ -122,12 +122,22 @@ class Module_bookmarks
 		{
 			if ($row['b_folder']!='') $list->attach(form_input_list_entry($row['b_folder']));
 		}
-		$fields->attach(form_input_list(do_lang_tempcode('OLD_BOOKMARK_FOLDER'),do_lang_tempcode('DESCRIPTION_OLD_BOOKMARK_FOLDER'),'folder',$list,NULL,false,false));
-		$fields->attach(form_input_line(do_lang_tempcode('NEW_BOOKMARK_FOLDER'),do_lang_tempcode('DESCRIPTION_NEW_BOOKMARK_FOLDER'),'folder_new','',false));
+
+		$set_name='choose_folder';
+		$required=true;
+		$set_title=do_lang_tempcode('BOOKMARK_FOLDER');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('DESCRIPTION_OLD_BOOKMARK_FOLDER'),'folder',$list,NULL,false,false));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('NEW'),do_lang_tempcode('DESCRIPTION_NEW_BOOKMARK_FOLDER'),'folder_new','',false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('ACTIONS'))));
 		$fields->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
 		$post_url=build_url(array('page'=>'_SELF','type'=>'_manage'),'_SELF');
-		$form=do_template('FORM',array('HIDDEN'=>'','FIELDS'=>$fields,'TEXT'=>'','URL'=>$post_url,'SUBMIT_NAME'=>do_lang_tempcode('MOVE_OR_DELETE_BOOKMARKS'),'JAVASCRIPT'=>'standardAlternateFields(\'folder\',\'folder_new\');'));
+		$form=do_template('FORM',array('HIDDEN'=>'','FIELDS'=>$fields,'TEXT'=>'','URL'=>$post_url,'SUBMIT_NAME'=>do_lang_tempcode('MOVE_OR_DELETE_BOOKMARKS')));
 
 		$bookmarks=array();
 		$_bookmarks=$GLOBALS['SITE_DB']->query_select('bookmarks',array('*'),array('b_owner'=>get_member()),'ORDER BY b_folder');
diff --git a/sources/banners2.php b/sources/banners2.php
index 2bd59d5..01bfc0e 100644
--- a/sources/banners2.php
+++ b/sources/banners2.php
@@ -76,9 +76,20 @@ function get_banner_form_fields($simplified=false,$name='',$image_url='',$site_u
 	}
 
 	$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('SOURCE_MEDIA'))));
-	$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD_BANNER'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-	$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('IMAGE_URL')),do_lang_tempcode('DESCRIPTION_URL_BANNER'),'image_url',$image_url,false));
-	$fields->attach(form_input_line_comcode(do_lang_tempcode('BANNER_TITLE_TEXT'),do_lang_tempcode('DESCRIPTION_BANNER_TITLE_TEXT'),'title_text',$title_text,false));
+
+	$set_name='media';
+	$required=false;
+	$set_title=do_lang_tempcode('MEDIA');
+	$field_set=alternate_fields_set__start($set_name);
+
+	$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD_BANNER'),'file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+	$field_set->attach(form_input_line(do_lang_tempcode('IMAGE_URL'),do_lang_tempcode('DESCRIPTION_URL_BANNER'),'image_url',$image_url,false));
+
+	$field_set->attach(form_input_line_comcode(do_lang_tempcode('BANNER_TITLE_TEXT'),do_lang_tempcode('DESCRIPTION_BANNER_TITLE_TEXT'),'title_text',$title_text,false));
+
+	$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 	$fields->attach(form_input_line_comcode(do_lang_tempcode('DESCRIPTION'),do_lang_tempcode('DESCRIPTION_BANNER_DESCRIPTION'),'caption',$caption,false));
 
 	$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('DEPLOYMENT_DETERMINATION'))));
diff --git a/sources/bookmarks.php b/sources/bookmarks.php
index 77c59df..0b6cf97 100755
--- a/sources/bookmarks.php
+++ b/sources/bookmarks.php
@@ -90,15 +90,25 @@ function add_bookmark_form($post_url)
 		if ($row['b_folder']!='') $list->attach(form_input_list_entry($row['b_folder']));
 	}
 	$fields=new ocp_tempcode();
-	$fields->attach(form_input_list(do_lang_tempcode('OLD_BOOKMARK_FOLDER'),do_lang_tempcode('DESCRIPTION_OLD_BOOKMARK_FOLDER'),'folder',$list,NULL,false,false));
-	$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('NEW_BOOKMARK_FOLDER')),do_lang_tempcode('DESCRIPTION_NEW_BOOKMARK_FOLDER'),'folder_new','',false));
+
+	$set_name='folder';
+	$required=true;
+	$set_title=do_lang_tempcode('BOOKMARK_FOLDER');
+	$field_set=alternate_fields_set__start($set_name);
+
+	$field_set->attach(form_input_list(do_lang_tempcode('EXISTING'),do_lang_tempcode('DESCRIPTION_OLD_BOOKMARK_FOLDER'),'folder',$list,NULL,false,false));
+
+	$field_set->attach(form_input_line(do_lang_tempcode('NEW'),do_lang_tempcode('DESCRIPTION_NEW_BOOKMARK_FOLDER'),'folder_new','',false));
+
+	$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 	$fields->attach(form_input_line(do_lang_tempcode('TITLE'),do_lang_tempcode('DESCRIPTION_TITLE'),'title',($default_title=='')?'':substr($default_title,0,200),true));
 	$fields->attach(form_input_line(do_lang_tempcode('PAGE_LINK'),do_lang_tempcode('DESCRIPTION_PAGE_LINK_BOOKMARK'),'page_link',$page_link,true));
 	$submit_name=do_lang_tempcode('ADD_BOOKMARK');
 
 	breadcrumb_set_parents(array(array('_SELF:_SELF:misc',do_lang_tempcode('MANAGE_BOOKMARKS'))));
 
-	$javascript='standardAlternateFields(\'folder\',\'folder_new\'); var title=document.getElementById(\'title\'); if (((title.value==\'\') || (title.value==\'0\')) && (window.opener)) title.value=getInnerHTML(window.opener.document.getElementsByTagName(\'title\')[0]); ';
+	$javascript='var title=document.getElementById(\'title\'); if (((title.value==\'\') || (title.value==\'0\')) && (window.opener)) title.value=getInnerHTML(window.opener.document.getElementsByTagName(\'title\')[0]); ';
 
 	return do_template('FORM_SCREEN',array('_GUID'=>'7e94bb97008de4fa0fffa2b5f91c95eb','TITLE'=>$title,'HIDDEN'=>'','TEXT'=>'','FIELDS'=>$fields,'URL'=>$post_url,'SUBMIT_NAME'=>$submit_name,'JAVASCRIPT'=>$javascript));
 }
diff --git a/sources/form_templates.php b/sources/form_templates.php
index 0a4afb8..7642b67 100644
--- a/sources/form_templates.php
+++ b/sources/form_templates.php
@@ -35,6 +35,9 @@ function init__form_templates()
 	$NO_DEBUG_MODE_FULLSTOP_CHECK=false;
 	
 	require_code('input_filter');
+
+	global $DOING_ALTERNATE_FIELDS_SET;
+	$DOING_ALTERNATE_FIELDS_SET=mixed();
 }
 
 /**
@@ -1269,7 +1272,7 @@ function form_input_picture_choose_specific($pretty_name,$description,$name,$ids
 
 	$input=do_template('FORM_SCREEN_INPUT_RADIO_LIST',array('NAME'=>$name,'CODE'=>is_null($selected_code)?'':$selected_code,'TABINDEX'=>strval($tabindex),'CONTENT'=>$content));
 
-	return _form_input('',$pretty_name,$description,$input,false);
+	return _form_input($GLOBALS['DOING_ALTERNATE_FIELDS_SET']?$name:'',$pretty_name,$description,$input,false);
 }
 
 /**
@@ -1550,9 +1553,44 @@ function form_input_float($pretty_name,$description,$name,$default,$required,$ta
 }
 
 /**
+ * Start off a field set.
+ *
+ * IMPORTANT: Note that this function uses global state -- any fields generated between alternate_fields_set__start and alternate_fields_set__end will be rendered using field set templating.
+ *
+ * @param  ID_TEXT		The codename for this field set
+ * @return tempcode		Tempcode to start attaching the field set to
+ */
+function alternate_fields_set__start($set_name)
+{
+	global $DOING_ALTERNATE_FIELDS_SET;
+	if (!is_null($DOING_ALTERNATE_FIELDS_SET)) warn_exit(do_lang_tempcode('INTERNAL_ERROR'));
+	$DOING_ALTERNATE_FIELDS_SET=$set_name;
+	return new ocp_tempcode();
+}
+
+/**
+ * Show a field set that has just been finished off.
+ *
+ * @param  ID_TEXT		The codename for this field set
+ * @param  mixed			The human-readable name for this field set
+ * @param  mixed			The human-readable description for this field set
+ * @param  tempcode		The field set tempcode
+ * @param  boolean		Whether it is required that this field set be filled in
+ * @return tempcode		The field set
+ */
+function alternate_fields_set__end($set_name,$pretty_name,$description,$fields,$required)
+{
+	$set=do_template('FORM_SCREEN_FIELDS_SET',array('FIELDS'=>$fields,'SET_NAME'=>$set_name,'REQUIRED'=>$required));
+	global $DOING_ALTERNATE_FIELDS_SET;
+	if (is_null($DOING_ALTERNATE_FIELDS_SET)) warn_exit(do_lang_tempcode('INTERNAL_ERROR'));
+	$DOING_ALTERNATE_FIELDS_SET=NULL;
+	return _form_input('',$pretty_name,$description,$set,$required);
+}
+
+/**
  * Helper function to show an input field.
  *
- * @param  ID_TEXT		The codename for this field
+ * @param  ID_TEXT		The codename for this field (blank: N/A)
  * @param  mixed			The human-readable name for this field
  * @param  mixed			The human-readable description for this field
  * @param  tempcode		The actual raw input field
@@ -1566,8 +1604,6 @@ function form_input_float($pretty_name,$description,$name,$default,$required,$ta
  */
 function _form_input($name,$pretty_name,$description,$input,$required,$comcode=false,$tabindex=NULL,$w=false,$skip_label=false,$description_side='')
 {
-	unset($tabindex); // Not currently used
-	
 	if (($GLOBALS['DEBUG_MODE']) && (user_lang()==fallback_lang()))
 	{
 		$_description=trim(strip_tags(is_object($description)?$description->evaluate():$description));
@@ -1579,6 +1615,13 @@ function _form_input($name,$pretty_name,$description,$input,$required,$comcode=f
 
 	$_comcode=$comcode?do_template('COMCODE_MESSAGE',array('_GUID'=>'7668b8365e34b2484be7c2c271f82e79','NAME'=>$name,'W'=>$w,'URL'=>build_url(array('page'=>'userguide_comcode'),get_comcode_zone('userguide_comcode',false)))):new ocp_tempcode();
 
+	global $DOING_ALTERNATE_FIELDS_SET;
+	if ($DOING_ALTERNATE_FIELDS_SET!==NULL)
+	{
+		$tpl=do_template('FORM_SCREEN_FIELDS_SET_ITEM',array('SET_NAME'=>$DOING_ALTERNATE_FIELDS_SET,'REQUIRED'=>$required,'SKIP_LABEL'=>$skip_label,'BORING_NAME'=>$name,'NAME'=>$pretty_name,'DESCRIPTION'=>$description,'DESCRIPTION_SIDE'=>$description_side,'INPUT'=>$input,'COMCODE'=>$_comcode));
+		return $tpl;
+	}
+
 	$tpl=do_template('FORM_SCREEN_FIELD',array('_GUID'=>'fa1402b7ad8319372f4bb5b152be7852','REQUIRED'=>$required,'SKIP_LABEL'=>$skip_label,'BORING_NAME'=>$name,'NAME'=>$pretty_name,'DESCRIPTION'=>$description,'DESCRIPTION_SIDE'=>$description_side,'INPUT'=>$input,'COMCODE'=>$_comcode));
 	return $tpl;
 }
diff --git a/sources/hooks/modules/pointstore/banners.php b/sources/hooks/modules/pointstore/banners.php
index afe12ef..891f3e6 100644
--- a/sources/hooks/modules/pointstore/banners.php
+++ b/sources/hooks/modules/pointstore/banners.php
@@ -104,7 +104,7 @@ class Hook_pointstore_banners
 
 		$this->handle_has_banner_already();
 
-		//We can purchase a banner...
+		// We can purchase a banner...
 		$initial_hits=intval(get_option('initial_banner_hits'));
 		$banner_price=intval(get_option('banner_setup'));
 		$text=paragraph(do_lang_tempcode('BANNERS_DESCRIPTION',integer_format($initial_hits),integer_format($banner_price)));
@@ -112,7 +112,7 @@ class Hook_pointstore_banners
 		$title=get_page_title('ADD_BANNER');
 		$post_url=build_url(array('page'=>'_SELF','type'=>'_newbanner','id'=>'banners','uploading'=>1),'_SELF');
 
-		$javascript='standardAlternateFields(\'file\',\'image_url\',\'title_text\',true); if (document.getElementById(\'campaignremaining\')) { var form=document.getElementById(\'campaignremaining\').form; var crf=function() { form.elements[\'campaignremaining\'].disabled=(!form.elements[\'the_type\'][1].checked); }; crf(); form.elements[\'the_type\'][0].onclick=crf; form.elements[\'the_type\'][1].onclick=crf; form.elements[\'the_type\'][2].onclick=crf; }';
+		$javascript='if (document.getElementById(\'campaignremaining\')) { var form=document.getElementById(\'campaignremaining\').form; var crf=function() { form.elements[\'campaignremaining\'].disabled=(!form.elements[\'the_type\'][1].checked); }; crf(); form.elements[\'the_type\'][0].onclick=crf; form.elements[\'the_type\'][1].onclick=crf; form.elements[\'the_type\'][2].onclick=crf; }';
 	
 		$hidden=new ocp_tempcode();
 		handle_max_file_size($hidden,'image');
diff --git a/sources/hooks/modules/pointstore/topic_pin.php b/sources/hooks/modules/pointstore/topic_pin.php
index c541999..3a8be6b 100644
--- a/sources/hooks/modules/pointstore/topic_pin.php
+++ b/sources/hooks/modules/pointstore/topic_pin.php
@@ -71,8 +71,16 @@ class Hook_pointstore_topic_pin
 		$fields=new ocp_tempcode();
 		if (get_forum_type()=='ocf')
 		{
-			$fields->attach(form_input_tree_list(do_lang_tempcode('FORUM_TOPIC'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
-			$fields->attach(form_input_integer(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('FORUM_TOPIC')),do_lang_tempcode('DESCRIPTION_FORUM_TOPIC_ID'),'manual_topic_id',NULL,false));
+			$set_name='topic';
+			$required=true;
+			$set_title=do_lang_tempcode('FORUM_TOPIC');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_tree_list(do_lang_tempcode('CHOOSE'),'','select_topic_id',NULL,'choose_forum_topic',array(),false));
+
+			$field_set->attach(form_input_integer(do_lang_tempcode('IDENTIFIER'),do_lang_tempcode('DESCRIPTION_FORUM_TOPIC_ID'),'manual_topic_id',NULL,false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
 		} else
 		{
 			$fields->attach(form_input_integer(do_lang_tempcode('FORUM_TOPIC'),do_lang_tempcode('ENTER_TOPIC_ID_MANUALLY'),'manual_topic_id',NULL,false));
@@ -80,7 +88,7 @@ class Hook_pointstore_topic_pin
 
 		$text=do_lang_tempcode('PIN_TOPIC_A',integer_format($cost),integer_format($points_left-$cost));
 
-		return do_template('FORM_SCREEN',array('_GUID'=>'8cabf882d5cbe4d354cc6efbcf92ebf9','TITLE'=>$title,'TEXT'=>$text,'URL'=>$next_url,'FIELDS'=>$fields,'HIDDEN'=>'','SUBMIT_NAME'=>do_lang_tempcode('PURCHASE'),'JAVASCRIPT'=>'standardAlternateFields(\'select_topic_id\',\'manual_topic_id\');'));
+		return do_template('FORM_SCREEN',array('_GUID'=>'8cabf882d5cbe4d354cc6efbcf92ebf9','TITLE'=>$title,'TEXT'=>$text,'URL'=>$next_url,'FIELDS'=>$fields,'HIDDEN'=>'','SUBMIT_NAME'=>do_lang_tempcode('PURCHASE')));
 	}
 
 	/**
diff --git a/sources/hooks/systems/addon_registry/core_form_interfaces.php b/sources/hooks/systems/addon_registry/core_form_interfaces.php
index 7ab28a7..8fcf762 100644
--- a/sources/hooks/systems/addon_registry/core_form_interfaces.php
+++ b/sources/hooks/systems/addon_registry/core_form_interfaces.php
@@ -90,6 +90,8 @@ class Hook_addon_registry_core_form_interfaces
 			'FORM_SCREEN.tpl',
 			'COMCODE_EDITOR.tpl',
 			'FORM_SCREEN_FIELD.tpl',
+			'FORM_SCREEN_FIELDS_SET_ITEM.tpl',
+			'FORM_SCREEN_FIELDS_SET.tpl',
 			'FORM_SCREEN_INPUT_ALL_AND_NOT.tpl',
 			'FORM_SCREEN_INPUT_DATE.tpl',
 			'FORM_SCREEN_INPUT_DATE_NULL.tpl',
@@ -368,6 +370,8 @@ class Hook_addon_registry_core_form_interfaces
 				'COMCODE_EDITOR_MICRO_BUTTON.tpl'=>'posting_form',
 				'FORM_SCREEN_INPUT_CODENAME.tpl'=>'form_screen_1',
 				'FORM_SCREEN_INPUT_LINE.tpl'=>'form_screen_1',
+				'FORM_SCREEN_FIELDS_SET_ITEM.tpl'=>'form_screen_1',
+				'FORM_SCREEN_FIELDS_SET.tpl'=>'form_screen_1',
 				'FORM_SCREEN_INPUT_USERNAME.tpl'=>'form_screen_2',
 				'FORM_DESCRIP_SEP.tpl'=>'form_descrip_sep',
 				'FORM_SCREEN_INPUT_AUTHOR.tpl'=>'form_screen_1',
@@ -437,8 +441,15 @@ class Hook_addon_registry_core_form_interfaces
 		$list =	new ocp_tempcode();
 
 		$name = placeholder_random_id();
-		$input = do_lorem_template('FORM_SCREEN_INPUT_LINE',array('MAXLENGTH'=>placeholder_number(),'TABINDEX'=>placeholder_number(),'REQUIRED'=>'','NAME'=>$name,'DEFAULT'=>''));
-		$fields->attach(do_lorem_template('FORM_SCREEN_FIELD',array('REQUIRED'=>true,'SKIP_LABEL'=>false,'BORING_NAME'=>$name,'NAME'=>lorem_word(),'DESCRIPTION'=>lorem_sentence_html(),'DESCRIPTION_SIDE'=>'','INPUT'=>$input,'COMCODE'=>'')));
+		$_input1 = do_lorem_template('FORM_SCREEN_INPUT_LINE',array('MAXLENGTH'=>placeholder_number(),'TABINDEX'=>placeholder_number(),'REQUIRED'=>'','NAME'=>$name.'1','DEFAULT'=>''));
+		$input1 = do_lorem_template('FORM_SCREEN_FIELDS_SET_ITEM',array('SET_NAME'=>$name,'REQUIRED'=>true,'SKIP_LABEL'=>false,'BORING_NAME'=>$name.'1','NAME'=>lorem_word(),'DESCRIPTION'=>lorem_sentence_html(),'DESCRIPTION_SIDE'=>'','INPUT'=>$_input1,'COMCODE'=>''));
+		$_input2 = do_lorem_template('FORM_SCREEN_INPUT_LINE',array('MAXLENGTH'=>placeholder_number(),'TABINDEX'=>placeholder_number(),'REQUIRED'=>'','NAME'=>$name.'2','DEFAULT'=>''));
+		$input2 = do_lorem_template('FORM_SCREEN_FIELDS_SET_ITEM',array('SET_NAME'=>$name,'REQUIRED'=>true,'SKIP_LABEL'=>false,'BORING_NAME'=>$name.'2','NAME'=>lorem_word(),'DESCRIPTION'=>lorem_sentence_html(),'DESCRIPTION_SIDE'=>'','INPUT'=>$_input2,'COMCODE'=>''));
+		$inputs = new ocp_tempcode();
+		$inputs->attach($_input1);
+		$inputs->attach($_input2);
+		$fieldset = do_lorem_template('FORM_SCREEN_FIELDS_SET',array('SET_NAME'=>$name,'FIELDS'=>$inputs,'REQUIRED'=>true));
+		$fields->attach(do_lorem_template('FORM_SCREEN_FIELD',array('REQUIRED'=>true,'SKIP_LABEL'=>false,'BORING_NAME'=>$name,'NAME'=>lorem_word(),'DESCRIPTION'=>lorem_sentence_html(),'DESCRIPTION_SIDE'=>'','INPUT'=>$fieldset,'COMCODE'=>'')));
 
 		$name = placeholder_random_id();
 		$input = do_lorem_template('FORM_SCREEN_INPUT_TEXT',array('RAW'=>true,'SCROLLS'=>'','TABINDEX'=>placeholder_number(),'REQUIRED'=>'','NAME'=>$name,'DEFAULT'=>''));
diff --git a/sources/hooks/systems/profiles_tabs_edit/avatar.php b/sources/hooks/systems/profiles_tabs_edit/avatar.php
index e8240be..ae743ec 100755
--- a/sources/hooks/systems/profiles_tabs_edit/avatar.php
+++ b/sources/hooks/systems/profiles_tabs_edit/avatar.php
@@ -113,14 +113,22 @@ class Hook_Profiles_Tabs_Edit_avatar
 		$hidden=new ocp_tempcode();
 		if (has_specific_permission($member_id_viewing,'own_avatars'))
 		{
-			$javascript='standardAlternateFields(\'avatar_file\',\'avatar_alt_url\',\'avatar_stock*\',true);';
-			$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'avatar_file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+			$set_name='avatar';
+			$required=false;
+			$set_title=do_lang_tempcode('IMAGE');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','avatar_file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','avatar_alt_url',$found_it?'':$avatar_url,false));
+
+			$field_set->attach(form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','avatar_stock',$ids,$avatar_url,NULL,NULL,false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 			handle_max_file_size($hidden,'image');
-			$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'avatar_alt_url',$found_it?'':$avatar_url,false));
-			$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('STOCK')),do_lang_tempcode('DESCRIPTION_ALTERNATE_STOCK'),'avatar_stock',$ids,$avatar_url,NULL,NULL,true));
 		} else
 		{
-			$javascript='';
 			$fields->attach(form_input_picture_choose_specific(do_lang_tempcode('STOCK'),'','avatar_stock',$ids,$avatar_url,NULL,NULL,true));
 		}
 
@@ -141,6 +149,8 @@ class Hook_Profiles_Tabs_Edit_avatar
 		$hidden=new ocp_tempcode();
 		$hidden->attach(form_input_hidden('submitting_avatar_tab','1'));
 
+		$javascript='';
+
 		return array($title,$fields,$text,$javascript,$order,$hidden);
 	}
 
diff --git a/sources/hooks/systems/profiles_tabs_edit/photo.php b/sources/hooks/systems/profiles_tabs_edit/photo.php
index a76ca02..770c48e 100755
--- a/sources/hooks/systems/profiles_tabs_edit/photo.php
+++ b/sources/hooks/systems/profiles_tabs_edit/photo.php
@@ -62,14 +62,34 @@ class Hook_Profiles_Tabs_Edit_photo
 		// UI fields
 		$fields=new ocp_tempcode();
 		require_code('form_templates');
-		$fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'),do_lang_tempcode('DESCRIPTION_UPLOAD'),'photo_file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-		$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'photo_url',$photo_url,false));
+
+		$set_name='photo';
+		$required=false;
+		$set_title=do_lang_tempcode('PHOTO');
+		$field_set=alternate_fields_set__start($set_name);
+
+		$field_set->attach(form_input_upload(do_lang_tempcode('UPLOAD'),'','photo_file',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+		$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','photo_url',$photo_url,false));
+
+		$fields->attach(alternate_fields_set__end($set_name,$set_title,'',$field_set,$required));
+
 		if (get_option('is_on_gd')=='0')
 		{
 			$thumb_width=get_option('thumb_width');
-			$fields->attach(form_input_upload(do_lang_tempcode('THUMBNAIL'),do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),'photo_file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
-			$fields->attach(form_input_line(do_lang_tempcode('ALT_FIELD',do_lang_tempcode('URL')),do_lang_tempcode('DESCRIPTION_ALTERNATE_URL'),'photo_thumb_url',$thumb_url,false));
+
+			$set_name='thumbnail';
+			$required=false;
+			$set_title=do_lang_tempcode('THUMBNAIL');
+			$field_set=alternate_fields_set__start($set_name);
+
+			$field_set->attach(form_input_upload(do_lang_tempcode('THUMBNAIL'),'','photo_file2',false,NULL,NULL,true,str_replace(' ','',get_option('valid_images'))));
+
+			$field_set->attach(form_input_line(do_lang_tempcode('URL'),'','photo_thumb_url',$thumb_url,false));
+
+			$fields->attach(alternate_fields_set__end($set_name,$set_title,do_lang_tempcode('DESCRIPTION_THUMBNAIL',escape_html($thumb_width)),$field_set,$required));
 		}
+
 		$hidden=new ocp_tempcode();
 		handle_max_file_size($hidden,'image');
 		$hidden->attach(form_input_hidden('submitting_photo_tab','1'));
diff --git a/themes/default/templates/FORM_SCREEN_FIELDS_SET.tpl b/themes/default/templates/FORM_SCREEN_FIELDS_SET.tpl
new file mode 100644
index 0000000..ea0e7d2
--- /dev/null
+++ b/themes/default/templates/FORM_SCREEN_FIELDS_SET.tpl
@@ -0,0 +1,9 @@
+<div id="set_wrapper_{SET_NAME*}">
+	{FIELDS}
+</div>
+
+<script type="text/javascript">// <![CDATA[
+	addEventListenerAbstract(window,'load',function () {
+		standardAlternateFieldsWithin('{SET_NAME;}',{$?,{REQUIRED},true,false});
+	} );
+//]]></script>
diff --git a/themes/default/templates/FORM_SCREEN_FIELDS_SET_ITEM.tpl b/themes/default/templates/FORM_SCREEN_FIELDS_SET_ITEM.tpl
new file mode 100755
index 0000000..0dcfeb1
--- /dev/null
+++ b/themes/default/templates/FORM_SCREEN_FIELDS_SET_ITEM.tpl
@@ -0,0 +1,38 @@
+<div>
+	<label for="choose_{BORING_NAME*}">
+		<input type="radio" name="{SET_NAME*}" id="choose_{BORING_NAME*}" />
+		{NAME*}
+	</label>
+
+	{+START,IF_NON_EMPTY,{COMCODE}}
+		<span class="comcode_supported">
+			<input type="hidden" name="comcode__{$GET,randomised_id}" value="1" />
+			{COMCODE}
+		</span>
+	{+END}
+</div>
+
+<div class="mini_indent">
+	{INPUT}
+
+	{+START,IF_NON_EMPTY,{DESCRIPTION}}
+		<div class="associated_caption{+START,IF,{$AND,{$EQ,{$SUBSTR_COUNT,{INPUT}, name="},2},{$EQ,{$SUBSTR_COUNT,{INPUT},type="file"},0},{$EQ,{$SUBSTR_COUNT,{INPUT},type="checkbox"},1}}} field_checkbox_description{+END}">
+			<input type="hidden" name="label_for__{BORING_NAME*}" value="{$TRIM,{$REPLACE,&lsquo;,',{$REPLACE,&rsquo;,',{$REPLACE,&ldquo;,&quot;,{$REPLACE,&rdquo;,&quot;,{$REPLACE,&raquo;, ,{$STRIP_TAGS,{NAME*}}}}}}}}" />
+			<label for="{BORING_NAME*}">{DESCRIPTION}</label>
+		</div>
+	{+END}
+
+	<div id="error_{$GET,randomised_id}" style="display: none" class="input_error_here"></div>
+
+	<input type="hidden" id="requirec__{$GET,randomised_id}" name="require__{BORING_NAME*}" value="{$?,{REQUIRED*},1,0}" />
+
+	<script type="text/javascript">// <![CDATA[
+		addEventListenerAbstract(window,'load',function () {
+			if (typeof window.setUpChangeMonitor!='undefined')
+			{
+				ch=document.getElementById('required__{$GET,randomised_id}');
+				if (ch) setUpChangeMonitor(ch.parentNode);
+			}
+		} );
+	//]]></script>
+</div>
diff --git a/themes/default/templates/FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_2.tpl b/themes/default/templates/FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_2.tpl
index 176e1ff..e0f52eb 100755
--- a/themes/default/templates/FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_2.tpl
+++ b/themes/default/templates/FORM_SCREEN_INPUT_RADIO_LIST_ENTRY_PICTURE_2.tpl
@@ -3,10 +3,10 @@
 	
 	<div{+START,IF,{$AND,{$JS_ON},{$MATCH_KEY_MATCH,adminzone:admin_themes,_WILD:members}}} class="accessibility_hidden"{+END}>
 	{+START,IF,{$NOT,{CHECKED}}}
-		<label for="{$FIX_ID*,j_{NAME}_{CODE}}"><input onclick="if (typeof window.deselectAltURL!='undefined') deselectAltURL(this.form); if (typeof window.main_form_very_simple!='undefined') this.form.submit(); cancelBubbling(event);" class="input_radio" type="radio" id="{$FIX_ID*,j_{NAME}_{CODE}}" name="{NAME*}" value="{CODE*}" /> {PRETTY*}</label>
+		<label for="{$FIX_ID*,j_{NAME}_{CODE}}"><input onclick="if (this.disabled) return; if (typeof window.deselectAltURL!='undefined') deselectAltURL(this.form); if (typeof window.main_form_very_simple!='undefined') this.form.submit(); cancelBubbling(event);" class="input_radio" type="radio" id="{$FIX_ID*,j_{NAME}_{CODE}}" name="{NAME*}" value="{CODE*}" /> {PRETTY*}</label>
 	{+END}
 	{+START,IF,{CHECKED}}
-		<label for="{$FIX_ID*,j_{NAME}_{CODE}}"><input onclick="if (typeof window.deselectAltURL!='undefined') deselectAltURL(this.form); if (typeof window.main_form_very_simple!='undefined') this.form.submit(); cancelBubbling(event);" class="input_radio" type="radio" id="{$FIX_ID*,j_{NAME}_{CODE}}" name="{NAME*}" value="{CODE*}" checked="checked" /> {PRETTY*}</label>
+		<label for="{$FIX_ID*,j_{NAME}_{CODE}}"><input onclick="if (this.disabled) return; if (typeof window.deselectAltURL!='undefined') deselectAltURL(this.form); if (typeof window.main_form_very_simple!='undefined') this.form.submit(); cancelBubbling(event);" class="input_radio" type="radio" id="{$FIX_ID*,j_{NAME}_{CODE}}" name="{NAME*}" value="{CODE*}" checked="checked" /> {PRETTY*}</label>
 	{+END}
 	</div>
 </div>
diff --git a/themes/default/templates/JAVASCRIPT_VALIDATION.tpl b/themes/default/templates/JAVASCRIPT_VALIDATION.tpl
index cdaa37f..9937d47 100644
--- a/themes/default/templates/JAVASCRIPT_VALIDATION.tpl
+++ b/themes/default/templates/JAVASCRIPT_VALIDATION.tpl
@@ -484,222 +484,287 @@ function checkForm(theForm,forPreview)
 	return !erroneous;
 }
 
-// Do dynamic setLocked/setRequired such that one of these must be set, but only one may be
-function standardAlternateFields(_a,_b,_c,non_actually_required)
+function standardAlternateFieldsWithin(set_name,something_required)
 {
-	if (typeof non_actually_required=='undefined') var non_actually_required=false; // Just to make sure it's a nice boolean
-
-	// Get field objects
-	var a=_standardAlternateFieldsGet(_a);
-	var b=_standardAlternateFieldsGet(_b);
-	var c;
-	if (_c) c=_standardAlternateFieldsGet(_c); // Third alternate is optional
-
-	// Set up listening if not already...
-	if (((a) && (!a.alternating)) || ((b) && (!b.alternating)) || ((c) && (!c.alternating))) // It is actually allowed for a single alternator, if circumstances have made the other one non-present (such as having GD support meaning a thumbnail isn't needed)
-	{
-		var selfFunction=function (e) { standardAlternateFields(_a,_b,_c,non_actually_required); } ; // We'll re-call ourself to do any fiddling
-
-		_standardAlternateFieldEventSet(a,selfFunction);
-		_standardAlternateFieldEventSet(b,selfFunction);
-		_standardAlternateFieldEventSet(c,selfFunction);
-	}
-
-	// Now, look at what is set, and disable/enable/require/non-require appropriately
-	if ((a) && (((a.value!='') && (a.value!='-1')) || ((a.virtual_value) && (a.virtual_value!='') && (a.virtual_value!='-1'))))
-		return _standardAlternateFieldsSet(a,b,c,non_actually_required);
-	if ((b) && (((b.value!='') && (b.value!='-1')) || ((b.virtual_value) && (b.virtual_value!='') && (b.virtual_value!='-1'))))
-		return _standardAlternateFieldsSet(b,a,c,non_actually_required);
-	if ((c) && (((c.value!='') && (c.value!='-1')) || ((c.virtual_value) && (c.virtual_value!='') && (c.virtual_value!='-1'))))
-		return _standardAlternateFieldsSet(c,a,b,non_actually_required);
-	// Nothing set...
-	if (a) _standardAlternateFieldSet(a,null,false,true,non_actually_required);
-	if (b) _standardAlternateFieldSet(b,null,false,true,non_actually_required);
-	if (c) _standardAlternateFieldSet(c,null,false,true,non_actually_required);
-	return null;
+	var form=document.getElementById('set_wrapper_'+set_name);
+	while (form.nodeName.toLowerCase()!='form')
+	{
+		form=form.parentNode;
+	}
+	var fields=form.elements[set_name];
+	var field_names=[];
+	for (var i=0;i<fields.length;i++)
+	{
+		if (typeof fields[i][0]=='undefined')
+		{
+			if (fields[i].id.match(/^choose\_/))
+				field_names.push(fields[i].id.replace(/^choose\_/,''));
+		} else
+		{
+			if (fields[i][0].id.match(/^choose\_/))
+				field_names.push(fields[i][0].id.replace(/^choose\_/,''));
+		}
+	}
+	standardAlternateFields(field_names,something_required);
 }
 
-function _standardAlternateFieldEventSet(a,selfFunction)
+// Do dynamic setLocked/setRequired such that one of these must be set, but only one may be
+function standardAlternateFields(field_names,something_required,second_run)
 {
-	if (a)
+	if (typeof second_run=='undefined') var second_run=false;
+
+	// Look up field objects
+	var fields=[];
+	for (var i=0;i<field_names.length;i++)
 	{
-		if (typeof a.name!='undefined')
+		var field=_standardAlternateFieldsGetObject(field_names[i]);
+		fields.push(field);
+	}
+
+	// Set up listeners...
+	for (var i=0;i<field_names.length;i++)
+	{
+		var field=fields[i];
+		if (typeof field.alternating=='undefined') // ... but only if not already set
 		{
-			addEventListenerAbstract(a,"keyup",selfFunction);
-			addEventListenerAbstract(a,"change",selfFunction);
-			a.fakeonchange=selfFunction;
-			a.alternating=true;
-		} else
+			var selfFunction=function (e) { standardAlternateFields(field_names,something_required,true); } ; // We'll re-call ourself on change
+			_standardAlternateFieldCreateListeners(field,selfFunction);
+		}
+	}
+
+	// Update things
+	for (var i=0;i<field_names.length;i++)
+	{
+		var field=fields[i];
+		if (_standardAlternateFieldIsFilledIn(field,second_run,false))
+			return _standardAlternateFieldUpdateEditability(field,fields,something_required);
+	}
+
+	// Hmm, force first one chosen then
+	for (var i=0;i<field_names.length;i++)
+	{
+		var field=fields[i];
+		if (_standardAlternateFieldIsFilledIn(field,second_run,true))
+			return _standardAlternateFieldUpdateEditability(field,fields,something_required);
+	}
+}
+
+function _standardAlternateFieldIsFilledIn(field,second_run,force)
+{
+	var is_set=force || ((field.value!='') && (field.value!='-1')) || ((typeof field.virtual_value!='undefined') && (field.virtual_value!='') && (field.virtual_value!='-1'));
+
+	var radio_button=document.getElementById('choose_'+field.name.replace(/\[\]$/,'')); // Radio button handles field alternation
+	if (second_run)
+	{
+		if (radio_button) return radio_button.checked;
+	} else
+	{
+		if (radio_button) radio_button.checked=is_set;
+	}
+	return is_set;
+}
+
+function _standardAlternateFieldCreateListeners(field,refreshFunction)
+{
+	if (typeof field.nodeName!='undefined')
+	{
+		__standardAlternateFieldCreateListeners(field,refreshFunction);
+	} else
+	{
+		var i;
+		for (i=0;i<field.length;i++)
 		{
-			var i;
-			for (i=0;i<a.length;i++)
-			{
-				addEventListenerAbstract(a[i],"keyup",selfFunction);
-				addEventListenerAbstract(a[i],"change",selfFunction);
-				a[i].fakeonchange=selfFunction;
-				a[i].alternating=true;
-			}
-			a.alternating=true;
+			if (typeof field[i].name!='undefined')
+				__standardAlternateFieldCreateListeners(field[i],refreshFunction);
 		}
+		field.alternating=true;
 	}
 	return null;
 }
 
-function _standardAlternateFieldsGet(x)
+function __standardAlternateFieldCreateListeners(field,refreshFunction)
 {
-	if (x.indexOf('*')==-1) // A normal field
+	var radio_button=document.getElementById('choose_'+field.name.replace(/\[\]$/,''));
+	if (radio_button) // Radio button handles field alternation
+	{
+		addEventListenerAbstract(radio_button,"change",refreshFunction);
+	} else // Filling/blanking out handles field alternation
 	{
-		return document.getElementById(x);
+		addEventListenerAbstract(field,"keyup",refreshFunction);
+		addEventListenerAbstract(field,"change",refreshFunction);
+		field.fakeonchange=refreshFunction;
 	}
-	
-	// A radio field ('*'), so we need to create a virtual field object to return that will hold our value
-	x=x.substr(0,x.length-1);
-	var _x=[],i,j,c=0,e;
-	_x['value']='';
+	field.alternating=true;
+}
+
+function _standardAlternateFieldsGetObject(field_name)
+{
+	var field=document.getElementById(field_name);
+	if (field) return field;
+
+	// A radio field, so we need to create a virtual field object to return that will hold our value
+	var radio_buttons=[],i,j,e;
+	radio_buttons['name']=field_name;
+	radio_buttons['value']='';
 	for (i=0;i<document.forms.length;i++)
 	{
 		for (j=0;j<document.forms[i].elements.length;j++)
 		{
 			e=document.forms[i].elements[j];
-			if (e.name==x)
+
+			if (e.name.replace(/\[\]$/,'')==field_name)
 			{
-				_x[c]=e;
+				radio_buttons.push(e);
 				if (e.checked) // This is the checked radio equivalent to our text field, copy the value through to the text field
 				{
-					_x['value']=e.value;
+					radio_buttons['value']=e.value;
 				}
-				if (e.alternating) _x.alternating=true;
-				c++;
+				if (e.alternating) radio_buttons.alternating=true;
 			}
 		}
 	}
 
-	return _x;
+	if (radio_buttons.length==0) return null;
+
+	return radio_buttons;
 }
 
-/*
-For this function...
-a is what is chosen
-b is what was not chosen [or null if not so many choices]
-c is what was not chosen [or null if not so many choices]
-*/
-function _standardAlternateFieldsSet(a,b,c,non_actually_required)
+function _standardAlternateFieldUpdateEditability(chosen,choices,something_required)
 {
-	if (a) _standardAlternateFieldSet(a,a,false,true,non_actually_required);
-	if (b) _standardAlternateFieldSet(b,a,true,false,non_actually_required);
-	if (c) _standardAlternateFieldSet(c,a,true,false,non_actually_required);
+	for (var i=0;i<choices.length;i++)
+	{
+		__standardAlternateFieldUpdateEditability(choices[i],chosen,choices[i]!=chosen,choices[i]==chosen,something_required);
+	}
 }
-
-/*
-Selected may only be null if locked is false
-*/
-function _standardAlternateFieldSet(us,selected,locked,required,non_actually_required)
+// NB: is_chosen may only be null if is_locked is false
+function __standardAlternateFieldUpdateEditability(field,chosen_field,is_locked,is_chosen,something_required)
 {
-	if (typeof us.name!='undefined')
+	if (typeof field.nodeName!='undefined')
 	{
-		setLocked(us.name,locked,selected);
-		if (!non_actually_required) setRequired(us.name,required);
-		var tr=us;
-		while ((tr) && (tr.nodeName.toLowerCase()!='tr'))
-		{
-			tr=tr.parentNode;
-		}
-		if ((tr) && (tr.nodeName.toLowerCase()=='tr'))
-			setOpacity(tr,locked?0.3:1.0);
-	} else
+		___standardAlternateFieldUpdateEditability(field,chosen_field,is_locked,is_chosen,something_required);
+	} else // Radio list
 	{
-		if (us[0])
-		{
-			if (!non_actually_required) setRequired(us[0].name,required);
-		}
-
-		var i;
-		for (i=0;i<us.length;i++)
+		for (var i=0;i<field.length;i++)
 		{
-			if (us[i].id) // If it is an object, as opposed to some string in the collection
+			if (typeof field[i].name!='undefined') // If it is an object, as opposed to some string in the collection
 			{
-				setLocked(us[i].id,locked,selected);
-				if (!non_actually_required) setRequired(us[i].id,required);
-				var tr=us[i];
-				while ((tr) && (tr.nodeName.toLowerCase()!='tr'))
-				{
-					tr=tr.parentNode;
-				}
-				if ((tr) && (tr.nodeName.toLowerCase()=='tr'))
-					setOpacity(tr,locked?0.3:1.0);
+				___standardAlternateFieldUpdateEditability(field[i],chosen_field,is_locked,is_chosen,something_required);
 			}
 		}
 	}
 }
+function ___standardAlternateFieldUpdateEditability(field,chosen_field,is_locked,is_chosen,something_required)
+{
+	var radio_button=document.getElementById('choose_'+field.name.replace(/\[\]$/,''));
+
+	setLocked(field,is_locked,chosen_field);
+	if (something_required)
+	{
+		setRequired(field.name.replace(/\[\]$/,''),is_chosen);
+	}
+	var tr=field;
+	while ((tr) && (tr.nodeName.toLowerCase()!='tr'))
+	{
+		tr=tr.parentNode;
+	}
+	if ((tr) && (tr.nodeName.toLowerCase()=='tr') && (!radio_button))
+		setOpacity(tr,is_locked?0.3:1.0);
+}
 
-function setLocked(name,locked,selected)
+function setLocked(field,is_locked,chosen_ob)
 {
+	var radio_button=document.getElementById('choose_'+field.name.replace(/\[\]$/,''));
+
 	// For All-and-not,Line-multi,Compound-Tick,Radio-List,Date/Time: setLocked assumes that the calling code is clever
 	// special input types are coded to observe their master input field readonly status)
-	var element=document.getElementById(name);
-	if (element)
+	var button=document.getElementById('uploadButton_'+field.name.replace(/\[\]$/,''));
+
+	if (is_locked)
 	{
-		if (locked)
+		var labels=document.getElementsByTagName('label'),label=null;
+		for (var i=0;i<labels.length;i++)
 		{
-			var labels=document.getElementsByTagName('label'),label=null;
-			for (var i=0;i<labels.length;i++)
+			if (labels[i].getAttribute('for')==chosen_ob.id)
 			{
-				if (labels[i].getAttribute('for')==selected.id)
-				{
-					label=labels[i];
-					break;
-				}
+				label=labels[i];
+				break;
 			}
+		}
+		if (!radio_button)
+		{
 			if (label)
 			{
 				var label_nice=getInnerHTML(label).replace('&raquo;','').replace('»','').replace(/^\s*/,'').replace(/\s*$/,'');
-				if (element.type=='file')
+				if (field.type=='file')
 				{
-					setFieldError(element,'{!DISABLED_FORM_FIELD_ENCHANCEDMSG_UPLOAD^;}'.replace(/\\{1\\}/,label_nice));
+					setFieldError(field,'{!DISABLED_FORM_FIELD_ENCHANCEDMSG_UPLOAD^;}'.replace(/\\{1\\}/,label_nice));
 				} else
 				{
-					setFieldError(element,'{!DISABLED_FORM_FIELD_ENCHANCEDMSG^;}'.replace(/\\{1\\}/,label_nice));
+					setFieldError(field,'{!DISABLED_FORM_FIELD_ENCHANCEDMSG^;}'.replace(/\\{1\\}/,label_nice));
 				}
 			} else
 			{
-				setFieldError(element,'{!DISABLED_FORM_FIELD^;}');
+				setFieldError(field,'{!DISABLED_FORM_FIELD^;}');
 			}
-			element.className=element.className.replace(/( input_erroneous($| ))+/g,' ');
-		} else
+		}
+		field.className=field.className.replace(/( input_erroneous($| ))+/g,' ');
+	} else
+	{
+		if (!radio_button)
 		{
-			setFieldError(element,'');
+			setFieldError(field,'');
 		}
-		element.disabled=locked;
 	}
+	field.disabled=is_locked;
+	if (button) button.disabled=is_locked;
 }
 
-function setRequired(name,required)
+function setRequired(field_name,is_required)
 {
-	var element=document.getElementById(name);
-	var required_a=document.getElementById('requirea__'+name);
-	var required_b=document.getElementById('requireb__'+name);
-	var required_c=document.getElementById('requirec__'+name);
-	var required_d=document.getElementById('required__'+name);
-	if (element) element.className=element.className.replace(/(input\_[a-z\_]+)_required/g,'$1');
-	if (required)
-	{
-		if (element) element.className=element.className.replace(/(input\_[a-z\_]+)/g,'$1_required');
-		if (required_a) required_a.className='de_th dottedborder_barrier_a_required';
-		if (required_d) required_d.className='dottedborder_barrier_b_required';
-		if (required_b) required_b.style.display='inline';
-		if (required_c) required_c.value=1;
+	var radio_button=document.getElementById('choose_'+field_name);
+
+	if (radio_button)
+	{
+		if (is_required) radio_button.checked=true;
 	} else
 	{
-		var error=document.getElementById('error__'+name);
-		if (error) error.style.display='none';
-		if (required_a) required_a.className='de_th dottedborder_barrier_a_nonrequired';
-		if (required_d) required_d.className='dottedborder_barrier_b_nonrequired';
-		if (required_b) required_b.style.display='none';
-		if (required_c) required_c.value=0;
+		var required_a=document.getElementById('requirea__'+field_name);
+		var required_b=document.getElementById('requireb__'+field_name);
+		var required_c=document.getElementById('requirec__'+field_name);
+		var required_d=document.getElementById('required__'+field_name);
+		if (is_required)
+		{
+			if (required_a) required_a.className='de_th dottedborder_barrier_a_required';
+			if (required_d) required_d.className='dottedborder_barrier_b_required';
+			if (required_b) required_b.style.display='inline';
+			if (required_c) required_c.value=1;
+		} else
+		{
+			if (required_a) required_a.className='de_th dottedborder_barrier_a_nonrequired';
+			if (required_d) required_d.className='dottedborder_barrier_b_nonrequired';
+			if (required_b) required_b.style.display='none';
+			if (required_c) required_c.value=0;
+		}
 	}
+
+	var element=document.getElementById(field_name);
+
 	if (element)
 	{
-		if (typeof element.swfob!='undefined') element.swfob.settings.required=required;
+		element.className=element.className.replace(/(input\_[a-z\_]+)_required/g,'$1');
+
+		if (typeof element.swfob!='undefined')
+		{
+			element.swfob.settings.required=is_required;
+		}
+
+		if (is_required) element.className=element.className.replace(/(input\_[a-z\_]+)/g,'$1_required');
+	}
+
+	if (!is_required)
+	{
+		var error=document.getElementById('error__'+field_name);
+		if (error) error.style.display='none';
 	}
 }
 
@@ -789,6 +854,7 @@ function choose_picture(id,ob,name)
 	{
 		for (var i=0;i<e.length;i++)
 		{
+			if (e[i].disabled) continue;
 			var img=e[i].parentNode.parentNode.getElementsByTagName('img')[0];
 			if ((img) && (img!=ob))
 			{
@@ -810,6 +876,7 @@ function choose_picture(id,ob,name)
 		}
 	}
 
+	if (r.disabled) return;
 	r.checked=true;
 	//if (r.onclick) r.onclick(); causes loop
 	ob.parentNode.onmouseover=function() {};
@@ -857,6 +924,7 @@ function setUpChangeMonitor(container,input,container2)
 	for (var i=0;i<elements.length;i++)
 	{
 		if (!elements[i]) continue;
+		if ((typeof elements[0]!='undefined') || (elements[0].id.indexOf('choose_')!=-1)) continue;
 		var func=function () {
 			if (findIfChildrenSet(input?document.getElementById(input).parentNode:container))
 			{
