diff --git a/ui (gen4)/features/ui-status.js b/ui (gen4)/features/ui-status.js
new file mode 100755
index 00000000..47787001
--- /dev/null
+++ b/ui (gen4)/features/ui-status.js	
@@ -0,0 +1,373 @@
+/**********************************************************************
+* 
+*
+*
+**********************************************************************/
+
+define(function(require){ var module = {}
+
+//var DEBUG = DEBUG != null ? DEBUG : true
+
+var toggler = require('lib/toggler')
+var actions = require('lib/actions')
+var features = require('lib/features')
+
+var data = require('data')
+var images = require('images')
+var ribbons = require('ribbons')
+
+var core = require('features/core')
+var base = require('features/base')
+
+
+
+/*********************************************************************/
+
+// XXX add setup / teardown...
+// XXX might be a good idea to merge this with single image mode...
+var makeStateIndicator = function(type){
+	return $('
')
+		.addClass('state-indicator-container ' + type || '')
+}
+
+// XXX do we need this???
+var makeStateIndicatorItem = function(container, type, text){
+	var item = $('
')
+			.addClass('item '+ type || '')
+			.attr('text', text)
+	this.ribbons.viewer.find('.state-indicator-container.'+container)
+		.append(item)
+	return item
+}
+
+// XXX should we use this or makeStateIndicatorItem(..)???
+// 		...investigate the features of the above...
+// 			- .attr('text')???
+var makeExpandingInfoItem = function(container, cls, align, full_only){
+	var e = $('
')
+		.addClass(cls + ' expanding-text ' + align +' '+ (full_only && 'full-only'))
+		.append($(''))
+		.append($(''))
+	container.append(e)
+	return e
+}
+var makeInfoItem = function(container, cls, align, full_only){
+	var e = $('')
+		.addClass(cls +' '+ align +' '+ (full_only && 'full_only'))
+	container.append(e)
+	return e
+} 
+
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+// XXX Add status messages and log...
+var ImageStateIndicatorActions = actions.Actions({
+	config: {
+		// XXX might be a good idea to add custom components API...
+		'global-state-indicator-elements': [
+			// XXX should index be here or to the right???
+			'index',
+			//'path',
+			'gid',
+
+			// separates left/right aligned elements...
+			'---',
+
+			'mark',
+			'bookmark',
+		],
+
+		'global-state-indicator-elements-full-only': [
+			'gid',
+		],
+
+		'global-state-indicator-modes': [
+			'none',
+			'minimal',
+			'full',
+		],
+		'global-state-indicator-mode': null,
+	},
+
+	get moo(){ return 321 },
+	foo: 123,
+
+	updateStateIndicators: ['- Interface/',
+		function(gid){
+			gid = gid || this.current
+
+			var that = this
+
+			// make/get indicator containers...
+			/*
+			var image = this.ribbons.viewer.find('.state-indicator-container.image-info')
+			if(image.length == 0){
+				image = makeStateIndicator('image-info') 
+					.appendTo(this.ribbons.viewer)
+			}
+			*/
+
+			var global = this.ribbons.viewer.find('.state-indicator-container.global-info')
+			if(global.length == 0){
+				//global = makeStateIndicator('global-info') 
+				global = makeStateIndicator('global-info overlay-info') 
+
+				var align = ''
+				var order = this.config['global-state-indicator-elements'].slice()
+
+				var i = order.indexOf('---')
+				// rearrange the tail section...
+				// NOTE: this is here as we need to push the floated
+				// 		right items in reverse order...
+				if(i >= 0){
+					order = order.concat(order.splice(i+1, order.length).reverse())
+				}
+
+				order.forEach(function(elem){
+					var full_only = that.config['global-state-indicator-elements-full-only'].indexOf(elem) >= 0
+					// spacer...
+					if(elem == '---'){
+						align = 'float-right'
+
+					// expanding indicators...
+					} else if(elem == 'gid' || elem == 'path'){
+						makeExpandingInfoItem(global, elem, align, full_only)
+
+					// simple indicators...
+					} else if(elem == 'index'){
+						makeInfoItem(global, elem, align, full_only)
+
+					// toggler indicators...
+					} else if(elem == 'bookmark' || elem == 'mark'){
+						makeInfoItem(global, elem+'ed', align, full_only)
+							.click(function(){
+								that['toggle'+elem.capitalize()]()
+							})
+
+					// XXX custom elements...
+					// 		format:
+					// 			{
+					// 				: ,
+					// 				: |,
+					// 				...
+					// 			}
+					// XXX the handler should take care of it's own updating...
+					// 		...will also need a way to drop a handler if 
+					// 		the list changes, otherwise this is a potential
+					// 		leak...
+					// XXX move other elements into this...
+					// XXX need a better attr name...
+					} else if(that.__state_indicator_elements){
+						var handler = that.__state_indicator_elements[elem]
+						// handle aliases...
+						var seen = []
+						while(typeof(handler) == typeof('str')){
+							seen.push(handler)
+							var handler = that.__state_indicator_elements[handler]
+							// check for loops...
+							if(seen.indexOf(handler) >= 0){
+								console.error('state indicator alias loop detected at:', elem)
+								handler = null
+							}
+						}
+
+						// do the call...
+						if(handler != null){
+							// XXX simplify the constructors... (into one?)
+							handler.call(that, elem, makeInfoItem, makeExpandingInfoItem)
+						}
+					}
+				})
+
+				global.appendTo(this.ribbons.viewer)
+
+				// init in the correct state...
+				if(this.config['global-state-indicator-mode']){
+					this.toggleStateIndicator(this.config['global-state-indicator-mode'])
+				}
+			}
+
+			if(!gid){
+				return
+			}
+
+
+			// populate the info...
+
+			var img = this.images && gid in this.images && this.images[gid]
+
+			// gid..
+			global.find('.gid .shown').text(gid.slice(-6))
+			global.find('.gid .hidden').text(gid)
+
+			// path...
+			global.find('.path .shown').text(img && img.path || '---')
+			global.find('.path .hidden').text(img && img.path || '---')
+
+			// pos...
+			global.find('.index')
+				.text(
+					(this.data.getImageOrder('ribbon', gid)+1) 
+					+'/'+ 
+					this.data.getImages(gid).len)
+
+			// NOTE: we are not using .toggleMark('?') and friends 
+			// 		here to avoid recursion as we might be handling 
+			// 		them here...
+			// 		...this also simpler than handling '?' and other
+			// 		special toggler args in the handler...
+			var tags = this.data.getTags(gid)
+
+			// marks...
+			global.find('.marked')[
+				tags.indexOf('selected') < 0 ?
+					'removeClass' 
+					: 'addClass']('on')
+			global.find('.bookmarked')[
+				tags.indexOf('bookmark') < 0 ? 
+					'removeClass' 
+					: 'addClass']('on')
+		}],
+	toggleStateIndicator: ['Interface/Toggle state indicator modes',
+		toggler.CSSClassToggler(
+			function(){ 
+				return this.ribbons.viewer.find('.state-indicator-container.global-info') }, 
+			function(){ return this.config['global-state-indicator-modes'] },
+			function(state){ this.config['global-state-indicator-mode'] = state }) ],
+})
+
+// XXX an alternative approach:
+// 		- global status area
+// 		- status bar for local status
+// 			- as in gen3
+// 			- add image status
+//
+// 		General item format:
+// 			- minimal state		- only short version / icon is shown
+// 								- when not active a disabled state/icon is shown
+//
+// 			- expanded state	- status bar sows expanded state (only?)
+// 								- title/help shown above 
+// 									- floating text, transparent bg
+// 									- same align as item
+//
+// XXX Q: can title bar be used instead of global state indication???
+// 		...especially if we are indicating only crop...
+// XXX add styling:
+// 		- element spacing
+// 		- tip text
+// 		- avoid multi-line
+// XXX rename to status bar???
+var ImageStateIndicator = 
+module.ImageStateIndicator = core.ImageGridFeatures.Feature({
+	title: '',
+	doc: '',
+
+	tag: 'ui-image-state-indicator',
+	depends: [
+		'ui',
+		'ui-single-image-view',
+	],
+
+	actions: ImageStateIndicatorActions,
+
+	handlers: [
+		['start',
+			function(){
+				if(this.config['global-state-indicator-mode']){
+					this.toggleStateIndicator(this.config['global-state-indicator-mode'])
+				}
+			}],
+		[[
+			'focusImage',
+			'toggleBookmark',
+			'toggleMark',
+		],
+			function(){
+				this.updateStateIndicators()
+			}]
+	],
+})
+
+
+
+//---------------------------------------------------------------------
+
+// XXX
+var GlobalStateIndicator = 
+module.GlobalStateIndicator = core.ImageGridFeatures.Feature({
+	title: '',
+	doc: '',
+
+	tag: 'ui-global-state-indicator',
+	depends: [
+		'ui'
+		//'ui-single-image-view',
+	],
+})
+
+
+
+//---------------------------------------------------------------------
+// XXX
+// XXX might also be a good idea to use the similar mechanism for tips...
+
+var StatusLogActions = actions.Actions({
+	config: {
+		// NOTE: if this is 0 then do not trim the log...
+		'ui-status-log-size': 100,
+
+		'ui-status-fade': 1000,
+	},
+
+	// XXX should this be here or in a separate feature???
+	statusLog: ['Interface/Show status log',
+		function(){
+			// XXX use list
+		}],
+	clearStatusLog: ['Interface/Clear status log',
+		function(){
+			delete this.__status_log
+		}],
+	statusMessage: ['- Interface/',
+		function(){
+			var msg = args2array(arguments)
+			if(msg.len == 0){
+				return
+			}
+			var log = this.__status_log = this.__status_log || []
+			
+			// XXX should we convert here and how???
+			log.push(msg.join(' '))
+
+			// truncate the log...
+			var s = this.config['ui-status-log-size']
+			if(s != 0 && log.length > (s || 100)){
+				log.splice(0, log.length - (s || 100))
+			}
+
+			// XXX show the message above the status bar (same style)...
+			// XXX
+		}],
+})
+
+var StatusLog = 
+module.StatusLog = core.ImageGridFeatures.Feature({
+	title: '',
+	doc: '',
+
+	tag: 'ui-status-log',
+	depends: [
+		'ui'
+	],
+
+	actions: StatusLogActions,
+})
+
+
+
+
+/**********************************************************************
+* vim:set ts=4 sw=4 :                                                */
+return module })
diff --git a/ui (gen4)/features/ui.js b/ui (gen4)/features/ui.js
index 62630f3f..f2a4165c 100755
--- a/ui (gen4)/features/ui.js	
+++ b/ui (gen4)/features/ui.js	
@@ -2482,353 +2482,6 @@ module.PassiveBaseRibbonIndicator = core.ImageGridFeatures.Feature({
 
 
 
-//---------------------------------------------------------------------
-
-
-// XXX add setup / teardown...
-// XXX might be a good idea to merge this with single image mode...
-var makeStateIndicator = function(type){
-	return $('')
-		.addClass('state-indicator-container ' + type || '')
-}
-
-// XXX do we need this???
-var makeStateIndicatorItem = function(container, type, text){
-	var item = $('
')
-			.addClass('item '+ type || '')
-			.attr('text', text)
-	this.ribbons.viewer.find('.state-indicator-container.'+container)
-		.append(item)
-	return item
-}
-
-// XXX should we use this or makeStateIndicatorItem(..)???
-// 		...investigate the features of the above...
-// 			- .attr('text')???
-var makeExpandingInfoItem = function(container, cls, align, full_only){
-	var e = $('
')
-		.addClass(cls + ' expanding-text ' + align +' '+ (full_only && 'full-only'))
-		.append($(''))
-		.append($(''))
-	container.append(e)
-	return e
-}
-var makeInfoItem = function(container, cls, align, full_only){
-	var e = $('')
-		.addClass(cls +' '+ align +' '+ (full_only && 'full_only'))
-	container.append(e)
-	return e
-} 
-
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-// XXX Add status messages and log...
-var ImageStateIndicatorActions = actions.Actions({
-	config: {
-		// XXX might be a good idea to add custom components API...
-		'global-state-indicator-elements': [
-			// XXX should index be here or to the right???
-			'index',
-			//'path',
-			'gid',
-
-			// separates left/right aligned elements...
-			'---',
-
-			'mark',
-			'bookmark',
-		],
-
-		'global-state-indicator-elements-full-only': [
-			'gid',
-		],
-
-		'global-state-indicator-modes': [
-			'none',
-			'minimal',
-			'full',
-		],
-		'global-state-indicator-mode': null,
-	},
-
-	get moo(){ return 321 },
-	foo: 123,
-
-	updateStateIndicators: ['- Interface/',
-		function(gid){
-			gid = gid || this.current
-
-			var that = this
-
-			// make/get indicator containers...
-			/*
-			var image = this.ribbons.viewer.find('.state-indicator-container.image-info')
-			if(image.length == 0){
-				image = makeStateIndicator('image-info') 
-					.appendTo(this.ribbons.viewer)
-			}
-			*/
-
-			var global = this.ribbons.viewer.find('.state-indicator-container.global-info')
-			if(global.length == 0){
-				//global = makeStateIndicator('global-info') 
-				global = makeStateIndicator('global-info overlay-info') 
-
-				var align = ''
-				var order = this.config['global-state-indicator-elements'].slice()
-
-				var i = order.indexOf('---')
-				// rearrange the tail section...
-				// NOTE: this is here as we need to push the floated
-				// 		right items in reverse order...
-				if(i >= 0){
-					order = order.concat(order.splice(i+1, order.length).reverse())
-				}
-
-				order.forEach(function(elem){
-					var full_only = that.config['global-state-indicator-elements-full-only'].indexOf(elem) >= 0
-					// spacer...
-					if(elem == '---'){
-						align = 'float-right'
-
-					// expanding indicators...
-					} else if(elem == 'gid' || elem == 'path'){
-						makeExpandingInfoItem(global, elem, align, full_only)
-
-					// simple indicators...
-					} else if(elem == 'index'){
-						makeInfoItem(global, elem, align, full_only)
-
-					// toggler indicators...
-					} else if(elem == 'bookmark' || elem == 'mark'){
-						makeInfoItem(global, elem+'ed', align, full_only)
-							.click(function(){
-								that['toggle'+elem.capitalize()]()
-							})
-
-					// XXX custom elements...
-					// 		format:
-					// 			{
-					// 				: ,
-					// 				: |,
-					// 				...
-					// 			}
-					// XXX the handler should take care of it's own updating...
-					// 		...will also need a way to drop a handler if 
-					// 		the list changes, otherwise this is a potential
-					// 		leak...
-					// XXX move other elements into this...
-					// XXX need a better attr name...
-					} else if(that.__state_indicator_elements){
-						var handler = that.__state_indicator_elements[elem]
-						// handle aliases...
-						var seen = []
-						while(typeof(handler) == typeof('str')){
-							seen.push(handler)
-							var handler = that.__state_indicator_elements[handler]
-							// check for loops...
-							if(seen.indexOf(handler) >= 0){
-								console.error('state indicator alias loop detected at:', elem)
-								handler = null
-							}
-						}
-
-						// do the call...
-						if(handler != null){
-							// XXX simplify the constructors... (into one?)
-							handler.call(that, elem, makeInfoItem, makeExpandingInfoItem)
-						}
-					}
-				})
-
-				global.appendTo(this.ribbons.viewer)
-
-				// init in the correct state...
-				if(this.config['global-state-indicator-mode']){
-					this.toggleStateIndicator(this.config['global-state-indicator-mode'])
-				}
-			}
-
-			if(!gid){
-				return
-			}
-
-
-			// populate the info...
-
-			var img = this.images && gid in this.images && this.images[gid]
-
-			// gid..
-			global.find('.gid .shown').text(gid.slice(-6))
-			global.find('.gid .hidden').text(gid)
-
-			// path...
-			global.find('.path .shown').text(img && img.path || '---')
-			global.find('.path .hidden').text(img && img.path || '---')
-
-			// pos...
-			global.find('.index')
-				.text(
-					(this.data.getImageOrder('ribbon', gid)+1) 
-					+'/'+ 
-					this.data.getImages(gid).len)
-
-			// NOTE: we are not using .toggleMark('?') and friends 
-			// 		here to avoid recursion as we might be handling 
-			// 		them here...
-			// 		...this also simpler than handling '?' and other
-			// 		special toggler args in the handler...
-			var tags = this.data.getTags(gid)
-
-			// marks...
-			global.find('.marked')[
-				tags.indexOf('selected') < 0 ?
-					'removeClass' 
-					: 'addClass']('on')
-			global.find('.bookmarked')[
-				tags.indexOf('bookmark') < 0 ? 
-					'removeClass' 
-					: 'addClass']('on')
-		}],
-	toggleStateIndicator: ['Interface/Toggle state indicator modes',
-		toggler.CSSClassToggler(
-			function(){ 
-				return this.ribbons.viewer.find('.state-indicator-container.global-info') }, 
-			function(){ return this.config['global-state-indicator-modes'] },
-			function(state){ this.config['global-state-indicator-mode'] = state }) ],
-})
-
-// XXX an alternative approach:
-// 		- global status area
-// 		- status bar for local status
-// 			- as in gen3
-// 			- add image status
-//
-// 		General item format:
-// 			- minimal state		- only short version / icon is shown
-// 								- when not active a disabled state/icon is shown
-//
-// 			- expanded state	- status bar sows expanded state (only?)
-// 								- title/help shown above 
-// 									- floating text, transparent bg
-// 									- same align as item
-//
-// XXX Q: can title bar be used instead of global state indication???
-// 		...especially if we are indicating only crop...
-// XXX add styling:
-// 		- element spacing
-// 		- tip text
-// 		- avoid multi-line -- scroll???
-// XXX rename to status bar???
-var ImageStateIndicator = 
-module.ImageStateIndicator = core.ImageGridFeatures.Feature({
-	title: '',
-	doc: '',
-
-	tag: 'ui-image-state-indicator',
-	depends: [
-		'ui',
-		'ui-single-image-view',
-	],
-
-	actions: ImageStateIndicatorActions,
-
-	handlers: [
-		['start',
-			function(){
-				if(this.config['global-state-indicator-mode']){
-					this.toggleStateIndicator(this.config['global-state-indicator-mode'])
-				}
-			}],
-		[[
-			'focusImage',
-			'toggleBookmark',
-			'toggleMark',
-		],
-			function(){
-				this.updateStateIndicators()
-			}]
-	],
-})
-
-
-
-//---------------------------------------------------------------------
-
-// XXX
-var GlobalStateIndicator = 
-module.GlobalStateIndicator = core.ImageGridFeatures.Feature({
-	title: '',
-	doc: '',
-
-	tag: 'ui-global-state-indicator',
-	depends: [
-		'ui'
-		//'ui-single-image-view',
-	],
-})
-
-
-
-//---------------------------------------------------------------------
-// XXX
-// XXX might also be a good idea to use the similar mechanism for tips...
-
-var StatusLogActions = actions.Actions({
-	config: {
-		// NOTE: if this is 0 then do not trim the log...
-		'ui-status-log-size': 100,
-
-		'ui-status-fade': 1000,
-	},
-
-	// XXX should this be here or in a separate feature???
-	statusLog: ['Interface/Show status log',
-		function(){
-			// XXX use list
-		}],
-	clearStatusLog: ['Interface/Clear status log',
-		function(){
-			delete this.__status_log
-		}],
-	statusMessage: ['- Interface/',
-		function(){
-			var msg = args2array(arguments)
-			if(msg.len == 0){
-				return
-			}
-			var log = this.__status_log = this.__status_log || []
-			
-			// XXX should we convert here and how???
-			log.push(msg.join(' '))
-
-			// truncate the log...
-			var s = this.config['ui-status-log-size']
-			if(s != 0 && log.length > (s || 100)){
-				log.splice(0, log.length - (s || 100))
-			}
-
-			// XXX show the message above the status bar (same style)...
-			// XXX
-		}],
-})
-
-var StatusLog = 
-module.StatusLog = core.ImageGridFeatures.Feature({
-	title: '',
-	doc: '',
-
-	tag: 'ui-status-log',
-	depends: [
-		'ui'
-	],
-
-	actions: StatusLogActions,
-})
-
-
-
 //---------------------------------------------------------------------
 // XXX experimental...
 
diff --git a/ui (gen4)/viewer.js b/ui (gen4)/viewer.js
index a6b1cfed..939abd48 100755
--- a/ui (gen4)/viewer.js	
+++ b/ui (gen4)/viewer.js	
@@ -32,6 +32,7 @@ var location = require('features/location')
 var history = require('features/history')
 var app = require('features/app')
 var ui = require('features/ui')
+var status = require('features/ui-status')
 var marks = require('features/ui-marks')
 var widgets = require('features/ui-widgets')
 var exteditor = require('features/external-editor')