<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/actions/action_function.erl</filename>
    </added>
    <added>
      <filename>www/bert.js</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -2,8 +2,6 @@
 &lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
 &lt;plist version=&quot;1.0&quot;&gt;
 &lt;dict&gt;
-	&lt;key&gt;currentDocument&lt;/key&gt;
-	&lt;string&gt;src/actions/action_update.erl&lt;/string&gt;
 	&lt;key&gt;documents&lt;/key&gt;
 	&lt;array&gt;
 		&lt;dict&gt;
@@ -78,8 +76,6 @@
 					&lt;string&gt;src/lib&lt;/string&gt;
 				&lt;/dict&gt;
 				&lt;dict&gt;
-					&lt;key&gt;expanded&lt;/key&gt;
-					&lt;true/&gt;
 					&lt;key&gt;name&lt;/key&gt;
 					&lt;string&gt;actions&lt;/string&gt;
 					&lt;key&gt;regexFolderFilter&lt;/key&gt;
@@ -112,8 +108,6 @@
 					&lt;string&gt;src/handlers&lt;/string&gt;
 				&lt;/dict&gt;
 			&lt;/array&gt;
-			&lt;key&gt;expanded&lt;/key&gt;
-			&lt;true/&gt;
 			&lt;key&gt;name&lt;/key&gt;
 			&lt;string&gt;SRC&lt;/string&gt;
 		&lt;/dict&gt;
@@ -215,34 +209,6 @@
 	&lt;integer&gt;279&lt;/integer&gt;
 	&lt;key&gt;metaData&lt;/key&gt;
 	&lt;dict&gt;
-		&lt;key&gt;src/actions/action_update.erl&lt;/key&gt;
-		&lt;dict&gt;
-			&lt;key&gt;caret&lt;/key&gt;
-			&lt;dict&gt;
-				&lt;key&gt;column&lt;/key&gt;
-				&lt;integer&gt;37&lt;/integer&gt;
-				&lt;key&gt;line&lt;/key&gt;
-				&lt;integer&gt;60&lt;/integer&gt;
-			&lt;/dict&gt;
-			&lt;key&gt;firstVisibleColumn&lt;/key&gt;
-			&lt;integer&gt;0&lt;/integer&gt;
-			&lt;key&gt;firstVisibleLine&lt;/key&gt;
-			&lt;integer&gt;39&lt;/integer&gt;
-		&lt;/dict&gt;
-		&lt;key&gt;src/lib/wf_context.erl&lt;/key&gt;
-		&lt;dict&gt;
-			&lt;key&gt;caret&lt;/key&gt;
-			&lt;dict&gt;
-				&lt;key&gt;column&lt;/key&gt;
-				&lt;integer&gt;0&lt;/integer&gt;
-				&lt;key&gt;line&lt;/key&gt;
-				&lt;integer&gt;120&lt;/integer&gt;
-			&lt;/dict&gt;
-			&lt;key&gt;firstVisibleColumn&lt;/key&gt;
-			&lt;integer&gt;0&lt;/integer&gt;
-			&lt;key&gt;firstVisibleLine&lt;/key&gt;
-			&lt;integer&gt;93&lt;/integer&gt;
-		&lt;/dict&gt;
 		&lt;key&gt;src/nitrogen.erl&lt;/key&gt;
 		&lt;dict&gt;
 			&lt;key&gt;caret&lt;/key&gt;
@@ -272,11 +238,6 @@
 			&lt;integer&gt;0&lt;/integer&gt;
 		&lt;/dict&gt;
 	&lt;/dict&gt;
-	&lt;key&gt;openDocuments&lt;/key&gt;
-	&lt;array&gt;
-		&lt;string&gt;src/actions/action_update.erl&lt;/string&gt;
-		&lt;string&gt;src/lib/wf_context.erl&lt;/string&gt;
-	&lt;/array&gt;
 	&lt;key&gt;showFileHierarchyDrawer&lt;/key&gt;
 	&lt;true/&gt;
 	&lt;key&gt;windowFrame&lt;/key&gt;</diff>
      <filename>Nitrogen.tmproj</filename>
    </modified>
    <modified>
      <diff>@@ -65,7 +65,7 @@
 -define(ELEMENT_BASE(Module), is_element=is_element, module=Module, id, actions, show_if=true, class=&quot;&quot;, style=&quot;&quot;).
 -record(elementbase, {?ELEMENT_BASE(undefined)}).
 -record(template, {?ELEMENT_BASE(element_template), file, bindings=[] }).
--record(function, {?ELEMENT_BASE(element_function), function=fun() -&gt; [] end}).
+-record(function_el, {?ELEMENT_BASE(element_function), function=fun() -&gt; [] end}).
 -record(body, {?ELEMENT_BASE(element_body), title=&quot;&quot;, body=[]}).
 -record(h1, {?ELEMENT_BASE(element_h1), text=&quot;&quot;, html_encode=true}).
 -record(h2, {?ELEMENT_BASE(element_h2), text=&quot;&quot;, html_encode=true}).
@@ -78,21 +78,21 @@
 -record(p, {?ELEMENT_BASE(element_p), body=&quot;&quot;}).
 -record(label, {?ELEMENT_BASE(element_label), text=&quot;&quot;, html_encode=true}).
 -record(value, {?ELEMENT_BASE(element_value), text=&quot;&quot;, html_encode=true}).
--record(link, {?ELEMENT_BASE(element_link), text=&quot;&quot;, body=&quot;&quot;, html_encode=true, url=&quot;javascript:&quot;, postback}).
+-record(link, {?ELEMENT_BASE(element_link), text=&quot;&quot;, body=&quot;&quot;, html_encode=true, url=&quot;javascript:&quot;, postback, delegate}).
 -record(error, {?ELEMENT_BASE(element_error), text=&quot;&quot;, html_encode=true}).
 -record(span, {?ELEMENT_BASE(element_span), text=&quot;&quot;, html_encode=true}).
--record(button, {?ELEMENT_BASE(element_button), text=&quot;Button&quot;, html_encode=true, postback}).
+-record(button, {?ELEMENT_BASE(element_button), text=&quot;Button&quot;, html_encode=true, postback, delegate}).
 -record(literal, {?ELEMENT_BASE(element_literal), text=&quot;&quot;, html_encode=true}).
--record(textbox, {?ELEMENT_BASE(element_textbox), text=&quot;&quot;, html_encode=true, next, postback}).
+-record(textbox, {?ELEMENT_BASE(element_textbox), text=&quot;&quot;, html_encode=true, next, postback, delegate}).
 -record(hidden, {?ELEMENT_BASE(element_hidden), text=&quot;&quot;, html_encode=true}).
 -record(textarea, {?ELEMENT_BASE(element_textarea), text=&quot;&quot;, html_encode=true}).
 -record(datepicker_textbox, {?ELEMENT_BASE(element_datepicker_textbox), text=&quot;&quot;, next, html_encode=true, validators=[], options = [{dateFormat, &quot;yy-mm-dd&quot;}] }).
--record(dropdown, {?ELEMENT_BASE(element_dropdown), options=[], html_encode=true, postback, value}).
+-record(dropdown, {?ELEMENT_BASE(element_dropdown), options=[], html_encode=true, postback, delegate, value}).
 -record(option, { text=&quot;&quot;, value=&quot;&quot;, selected=false }).
--record(checkbox, {?ELEMENT_BASE(element_checkbox), text=&quot;&quot;, html_encode=true, checked=false, postback}).
+-record(checkbox, {?ELEMENT_BASE(element_checkbox), text=&quot;&quot;, html_encode=true, checked=false, postback, delegate}).
 -record(radiogroup, {?ELEMENT_BASE(element_radiogroup), body=[]}).
--record(radio, {?ELEMENT_BASE(element_radio), text=&quot;&quot;, html_encode=true, value, name, checked=false, postback}).
--record(password, {?ELEMENT_BASE(element_password), text=&quot;&quot;, html_encode=true, next, postback}).
+-record(radio, {?ELEMENT_BASE(element_radio), text=&quot;&quot;, html_encode=true, value, name, checked=false, postback, delegate}).
+-record(password, {?ELEMENT_BASE(element_password), text=&quot;&quot;, html_encode=true, next, postback, delegate}).
 -record(panel, {?ELEMENT_BASE(element_panel), body=&quot;&quot;}).
 -record(spinner, {?ELEMENT_BASE(element_spinner), image=&quot;/nitrogen/spinner.gif&quot;}).
 -record(image, {?ELEMENT_BASE(element_image), image=&quot;&quot;, alt}).
@@ -124,9 +124,10 @@
 -record(comet, {?ACTION_BASE(action_comet), pool=undefined, scope=local, function, dying_message}).
 -record(continue, {?ACTION_BASE(action_continue), function, delegate, tag, timeout}).
 -record(api, {?ACTION_BASE(action_api), name, tag, delegate }).
+-record(function, {?ACTION_BASE(action_function), function }).
 -record(set, {?ACTION_BASE(action_set), value}).
 -record(redirect, {?ACTION_BASE(action_redirect), url}).
--record(event, {?ACTION_BASE(action_event), type=default, delay=0, postback, delegate, extra_param}).
+-record(event, {?ACTION_BASE(action_event), type=default, keycode=undefined, delay=0, postback, delegate, extra_param}).
 -record(validate, {?ACTION_BASE(action_validate), on=submit, success_text=&quot; &quot;, validators, attach_to }).
 -record(validation_error, {?ACTION_BASE(action_validation_error), text=&quot;&quot; }).
 -record(alert, {?ACTION_BASE(action_alert), text=&quot;&quot;}).</diff>
      <filename>include/wf.inc</filename>
    </modified>
    <modified>
      <diff>@@ -47,17 +47,15 @@ comet(F) -&gt;
 	
 %% @doc Convenience method to start a comet process.
 comet(F, Pool) -&gt;
-	SeriesID = wf_context:series_id(),
-	wf:wire(#comet { function=F, pool=Pool, scope=local }),
-	{ok, PoolPid} = get_pool_pid(SeriesID, Pool, local),
-	PoolPid.
+    Pid = spawn_with_context(F),
+	wf:wire(#comet { function=Pid, pool=Pool, scope=local }),
+	{ok, Pid}.
 	
 %% @doc Convenience method to start a comet process with global pool.
 comet_global(F, Pool) -&gt;
-	SeriesID = wf_context:series_id(),
-	wf:wire(#comet { function=F, pool=Pool, scope=global }),
-	{ok, PoolPid} = get_pool_pid(SeriesID, Pool, global),
-	PoolPid.
+    Pid = spawn_with_context(F),
+	wf:wire(#comet { function=Pid, pool=Pool, scope=global }),
+	{ok, Pid}.
 			
 %% @doc Gather all wired actions, and send to the accumulator.
 flush() -&gt;
@@ -111,9 +109,10 @@ event({spawn_async_function, Record}) -&gt;
 	{ok, PoolPid} = get_pool_pid(SeriesID, Pool, Scope), 
 	
 	% Create a process for the AsyncFunction...
-	AsyncFunction = Record#comet.function,
-	Context = wf_context:context(),
-	FunctionPid = erlang:spawn(fun() -&gt; wf_context:context(Context), AsyncFunction(), flush() end),
+	FunctionPid = case Record#comet.function of
+	    F when is_function(F) -&gt; spawn_with_context(F);
+	    P when is_pid(P) -&gt; P
+	end,
 	
 	% Create a process for the AsyncGuardian...
 	DyingMessage = Record#comet.dying_message,
@@ -128,6 +127,8 @@ event({spawn_async_function, Record}) -&gt;
 		&quot;if (!document.comet_started) { document.comet_started=true; &quot;, make_async_event(0), &quot; }&quot;
 	],
 	wf:wire(Actions);
+	
+
 		
 % This clause is the heart of async functions. It
 % is first triggered by the event/1 function above,
@@ -187,12 +188,17 @@ get_pool_pid(SeriesID, Pool, Scope) -&gt;
 % and is responsible for distributing messages to all processes in the pool.
 pool_loop(Processes) -&gt; 
 	receive
-		{add_process, Pid} -&gt;
-			erlang:monitor(process, Pid), 
-			pool_loop([Pid|Processes]);
+		{add_process, JoinPid} -&gt;
+			erlang:monitor(process, JoinPid), 
+			case Processes of
+			    [] -&gt; JoinPid!'INIT';
+			    _  -&gt; [Pid!{'JOIN', JoinPid} || Pid &lt;- Processes]
+			end,
+			pool_loop([JoinPid|Processes]);
 			
-		{'DOWN', _, process, Pid, _} -&gt;
-			pool_loop(Processes -- [Pid]);
+		{'DOWN', _, process, LeavePid, _} -&gt;
+		    [Pid!{'LEAVE', LeavePid} || Pid &lt;- Processes],
+			pool_loop(Processes -- [LeavePid]);
 			
 		Message -&gt;
 			[Pid!Message || Pid &lt;- Processes],
@@ -233,11 +239,11 @@ accumulator_loop(Guardians, Actions, Waiting, TimerRef) -&gt;
 			accumulator_loop(Guardians, [], Pid, TimerRef);
 			
 		{get_actions_blocking, Pid} when Actions /= [] -&gt;
-			Pid!{actions, Actions},
+			Pid!{actions, lists:reverse(Actions)},
 			accumulator_loop(Guardians, [], none, TimerRef);
 
 		{get_actions, Pid} -&gt;
-			Pid!{actions, Actions},
+			Pid!{actions, lists:reverse(Actions)},
 			accumulator_loop(Guardians, [], none, TimerRef);
 			
 		{set_lease, LengthInMS} -&gt;
@@ -265,13 +271,19 @@ guardian_process(FunctionPid, AccumulatorPid, PoolPid, DyingMessage) -&gt;
 		{'DOWN', _, process, FunctionPid, _} -&gt;
 			% The AsyncFunction process has died. 
 			% Communicate dying_message to the pool and exit.
-			PoolPid!DyingMessage;
+			case DyingMessage of
+			    undefined -&gt; ignore;
+			    _ -&gt; PoolPid!DyingMessage
+			end;
 			
 		{'DOWN', _, process, AccumulatorPid, _} -&gt; 
 			% The accumulator process has died. 
 			% Communicate dying_message to the pool, 
 			% kill the AsyncFunction process, and exit.
-			PoolPid!DyingMessage,
+			case DyingMessage of
+			    undefined -&gt; ignore;
+			    _ -&gt; PoolPid!DyingMessage
+			end,
 			erlang:exit(FunctionPid, async_die);
 		
 		{'DOWN', _, process, PoolPid, _} -&gt;
@@ -286,8 +298,13 @@ guardian_process(FunctionPid, AccumulatorPid, PoolPid, DyingMessage) -&gt;
 
 %%% PRIVATE FUNCTIONS %%%
 
+spawn_with_context(Function) -&gt;
+	Context = wf_context:context(),
+	erlang:spawn(fun() -&gt; wf_context:context(Context), wf_context:clear_actions(), Function(), flush() end).
+
+
 inner_send(Pool, Scope, Message) -&gt;
-	?PRINT({Pool, Scope, Message}),
+	% ?PRINT({Pool, Scope, Message}),
 	SeriesID = wf_context:series_id(),
 	{ok, PoolPid} = get_pool_pid(SeriesID, Pool, Scope),
 	PoolPid!Message,</diff>
      <filename>src/actions/action_comet.erl</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@
 -include (&quot;wf.inc&quot;).
 -compile(export_all).
 
-render_action(#event { postback=Postback, actions=Actions, trigger=Trigger, target=Target, type=Type, delay=Delay, delegate=Delegate, extra_param=ExtraParam}) -&gt; 
+render_action(#event { postback=Postback, actions=Actions, trigger=Trigger, target=Target, type=Type, keycode=KeyCode, delay=Delay, delegate=Delegate, extra_param=ExtraParam}) -&gt; 
 	PostbackScript = wf_event:generate_postback_script(Postback, Trigger, Target, Delegate, ExtraParam),
 	SystemPostbackScript = wf_event:generate_system_postback_script(Postback, Trigger, Target, Delegate),
 	WireAction = #wire { trigger=Trigger, target=Target, actions=Actions },
@@ -29,14 +29,25 @@ render_action(#event { postback=Postback, actions=Actions, trigger=Trigger, targ
 			];
 			
 		%%% USER EVENTS %%%
-		% Run the event when an enter key is hit, such as in an input textbox
+		
+		% Handle keypress, keydown, or keyup when a keycode is defined...
+	    _ when (Type==keypress orelse Type==keydown orelse Type==keyup) andalso (KeyCode /= undefined) -&gt;
+		    [
+				wf:f(&quot;Nitrogen.$observe_event(obj('~s'), '~s', function anonymous(event) {&quot;, [wf:to_js_id(Trigger), Type]),
+				wf:f(&quot;if (Nitrogen.$is_key_code(event, ~p)) { &quot;, [KeyCode]),
+				PostbackScript, WireAction,
+				&quot;return false; }});&quot;
+		    ];
+
+		% Convenience method for Enter Key...
 		enterkey -&gt;
 			[
-				wf:f(&quot;Nitrogen.$observe_event(obj('~s'), 'keypress', function anonymous(event) {&quot;, [wf:to_js_id(Trigger)]),
-				&quot;if (Nitrogen.$is_enter_key(event)) {&quot;, PostbackScript, WireAction, &quot;return false; }&quot;,
-				&quot;});&quot;
+				wf:f(&quot;Nitrogen.$observe_event(obj('~s'), '~s', function anonymous(event) {&quot;, [wf:to_js_id(Trigger), keydown]),
+				wf:f(&quot;if (Nitrogen.$is_key_code(event, ~p)) { &quot;, [13]),
+				PostbackScript, WireAction,
+				&quot;return false; }});&quot;
 			];
-		
+					
 		% Run the event after a specified amount of time
 		timer -&gt;
 			TempID = wf:temp_id(),</diff>
      <filename>src/actions/action_event.erl</filename>
    </modified>
    <modified>
      <diff>@@ -8,10 +8,17 @@
 
 % This action is used internally by Nitrogen.
 render_action(Record) -&gt;
-	DefaultTrigger = Record#wire.trigger,
-	DefaultTarget = Record#wire.target,
-	Actions = set_paths(DefaultTrigger, DefaultTarget, Record#wire.actions),
-	[Actions].
+    try 
+    	DefaultTrigger = Record#wire.trigger,
+    	DefaultTarget = Record#wire.target,
+    	Actions = set_paths(DefaultTrigger, DefaultTarget, Record#wire.actions),
+    	[Actions]
+    catch Type : Error -&gt;
+        ?PRINT(Type),
+        ?PRINT(Error),
+        ?PRINT(Record),
+        erlang:Type(Error)
+    end.
 	
 set_paths(_DefaultTrigger, _DefaultTarget, []) -&gt; 
 	[];
@@ -40,7 +47,7 @@ wire(TriggerID, TargetID, Script) when ?IS_STRING(Script) -&gt;
 wire(TriggerID, TargetID, Actions) -&gt;
 	CurrentPath = wf_context:current_path(),
 	Action = #wire { trigger=CurrentPath, target=CurrentPath, actions=[
-		#wire { 
+		#wire {
 			trigger=wf:coalesce([TriggerID, CurrentPath]),
 			target=wf:coalesce([TargetID, CurrentPath]),
 			actions=Actions</diff>
      <filename>src/actions/action_wire.erl</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ reflect() -&gt; record_info(fields, button).
 render_element(HtmlID, Record) -&gt;
 	case Record#button.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#button.id, #event { type=click, postback=Postback })
+		Postback -&gt; wf:wire(Record#button.id, #event { type=click, postback=Postback, delegate=Record#button.delegate })
 	end,
 	
 	Value = [&quot;  &quot;, wf:html_encode(Record#button.text, Record#button.html_encode), &quot;  &quot;], </diff>
      <filename>src/elements/forms/element_button.erl</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,7 @@ render_element(HtmlID, Record) -&gt;
 	end,
 	case Record#checkbox.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#checkbox.id, #event { type=change, postback=Postback })
+		Postback -&gt; wf:wire(Record#checkbox.id, #event { type=change, postback=Postback, delegate=Record#checkbox.delegate })
 	end,
 	
 	Text = wf:html_encode(Record#checkbox.text, Record#checkbox.html_encode),</diff>
      <filename>src/elements/forms/element_checkbox.erl</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,7 @@ render_element(HtmlID, Record) -&gt;
 	end,
 	case Record#password.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#password.id, #event { type=enterkey, postback=Postback })
+		Postback -&gt; wf:wire(Record#password.id, #event { type=enterkey, postback=Postback, delegate=Record#password.delegate })
 	end,
 
 	Value = wf:html_encode(Record#password.text, Record#password.html_encode),</diff>
      <filename>src/elements/forms/element_password.erl</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@ render_element(HtmlID, Record) -&gt;
 
 	case Record#radio.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#radio.id, #event { type=change, postback=Postback })
+		Postback -&gt; wf:wire(Record#radio.id, #event { type=change, postback=Postback, delegate=Record#radio.delegate })
 	end,
 
 	Content = wf:html_encode(Record#radio.text, Record#radio.html_encode),</diff>
      <filename>src/elements/forms/element_radio.erl</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@ render_element(HtmlID, Record) -&gt;
 
 	case Record#textbox.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#textbox.id, #event { type=enterkey, postback=Postback })
+		Postback -&gt; wf:wire(Record#textbox.id, #event { type=enterkey, postback=Postback, delegate=Record#textbox.delegate })
 	end,
 	
 	Value = wf:html_encode(Record#textbox.text, Record#textbox.html_encode),</diff>
      <filename>src/elements/forms/element_textbox.erl</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ reflect() -&gt; record_info(fields, link).
 render_element(HtmlID, Record) -&gt; 
 	case Record#link.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#link.id, #event { type=click, postback=Postback })
+		Postback -&gt; wf:wire(Record#link.id, #event { type=click, postback=Postback, delegate=Record#link.delegate })
 	end,
 	
 	Body = [</diff>
      <filename>src/elements/html/element_link.erl</filename>
    </modified>
    <modified>
      <diff>@@ -20,7 +20,11 @@ render_element(HtmlID, Record) -&gt;
 			#table { 
 				style=&quot;position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 99; overflow:auto;&quot;, 
 				rows=#tablerow {
-					cells=#tablecell { align=center, valign=middle, style=&quot;vertical-align: middle;&quot;, body=Record#lightbox.body } 
+					cells=#tablecell { align=center, valign=middle, style=&quot;vertical-align: middle;&quot;, body=[
+					    &quot;&lt;center&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&quot;,
+					    Record#lightbox.body,
+					    &quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/center&gt;&quot;
+				    ]} 
 				}
 			}
 		]</diff>
      <filename>src/elements/layout/element_lightbox.erl</filename>
    </modified>
    <modified>
      <diff>@@ -111,11 +111,11 @@ eval([script|T], Record) -&gt; [script|eval(T, Record)];
 eval([H|T], Record) when ?IS_STRING(H) -&gt; [H|eval(T, Record)];
 eval([H|T], Record) -&gt; [replace_callbacks(H, Record)|eval(T, Record)].
 
-% Turn callbacks into a reference to #function {}.
+% Turn callbacks into a reference to #function_el {}.
 replace_callbacks(CallbackTuples, Record) -&gt;
 	Bindings = Record#template.bindings,
 	Functions = [convert_callback_tuple_to_function(M, F, ArgString, Bindings) || {M, F, ArgString} &lt;- CallbackTuples],
-	#function { function=Functions }.
+	#function_el { function=Functions }.
 	
 convert_callback_tuple_to_function(Module, Function, ArgString, Bindings) -&gt;
 	% De-reference to page module...</diff>
      <filename>src/elements/layout/element_template.erl</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ reflect() -&gt; record_info(fields, dropdown).
 render_element(HtmlID, Record) -&gt; 
 	case Record#dropdown.postback of
 		undefined -&gt; ignore;
-		Postback -&gt; wf:wire(Record#dropdown.id, #event { type=change, postback=Postback })
+		Postback -&gt; wf:wire(Record#dropdown.id, #event { type=change, postback=Postback, delegate=Record#dropdown.delegate })
 	end,
 
 	case Record#dropdown.value of </diff>
      <filename>src/elements/other/element_dropdown.erl</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@
 -include (&quot;wf.inc&quot;).
 -compile(export_all).
 
-% The 'function' attribute is an Erlang function of arity 0 that returns {ok, [Elements]}.
+% The 'function' attribute is an Erlang function of arity 0 that returns [Elements].
 %
 % Elements can either be a String, a binary, more Nitrogen elements, or a combination thereof. 
 %
@@ -15,10 +15,10 @@
 % one that exists and returns a value (not undefined) will
 % be used.
 
-reflect() -&gt; record_info(fields, function).
+reflect() -&gt; record_info(fields, function_el).
 
 render_element(_HtmlID, Record) -&gt;
-	Functions = lists:flatten([Record#function.function]),
+	Functions = lists:flatten([Record#function_el.function]),
 	call_next_function(Functions).
 	
 call_next_function([]) -&gt; [];</diff>
      <filename>src/elements/other/element_function.erl</filename>
    </modified>
    <modified>
      <diff>@@ -77,9 +77,11 @@ try_load_module(Tokens, ExtraTokens) -&gt;
 	BeamFile = string:join(Tokens, &quot;_&quot;) ++ &quot;.beam&quot;,
 	case erl_prim_loader:get_file(BeamFile) of
 		{ok, _, _} -&gt; 
-			{list_to_atom(string:join(Tokens, &quot;_&quot;)), string:join(lists:reverse(ExtraTokens), &quot;/&quot;)};
-		undefined -&gt; 
-			try_load_module(tl(lists:reverse(Tokens)), [hd(lists:reverse(Tokens))|ExtraTokens])
+			{list_to_atom(string:join(Tokens, &quot;_&quot;)), string:join(ExtraTokens, &quot;/&quot;)};
+		_ -&gt; 
+		    Tokens1 = lists:reverse(tl(lists:reverse(Tokens))),
+		    ExtraTokens1 = [hd(lists:reverse(Tokens))|ExtraTokens],
+			try_load_module(Tokens1, ExtraTokens1)
 	end.
 	
 </diff>
      <filename>src/handlers/route/dynamic_route_handler.erl</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@
 ]).
 
 init(State) -&gt; 
-	% Deserialize the state from domState.	
+	% Deserialize the state from domState.
 	{ok, State}.
 
 finish(State) -&gt;</diff>
      <filename>src/handlers/state/default_state_handler.erl</filename>
    </modified>
    <modified>
      <diff>@@ -14,10 +14,11 @@
 
 split_dom_paths(undefined) -&gt; [?BASEPATH];
 split_dom_paths(DomPathList) -&gt; 
-	{ Paths, _} = split_dom_paths(DomPathList, []),
-	case lists:member(?BASEPATH, Paths) of
-		true -&gt; Paths;
-		false -&gt; [?BASEPATH|Paths]
+	{Paths, _} = split_dom_paths(DomPathList, []),
+	Paths1 = [X || X &lt;- Paths, X /= []],
+	case lists:member(?BASEPATH, Paths1) of
+		true -&gt; Paths1;
+		false -&gt; [?BASEPATH|Paths1]
 	end.
 
 split_dom_paths(DomPaths, Acc) -&gt;
@@ -74,7 +75,7 @@ normalize_path(Path) when is_list(Path) -&gt;
 	DomPaths = wf_context:dom_paths(),
 	% Find the one matching dom path.
 	case find_matching_dom_path(Path, DomPaths) of
-		[] -&gt; throw({no_matching_dom_paths, Path, DomPaths});
+		[] -&gt; throw({dom_path_error, no_matching_paths});
 		[Match] -&gt; Match;
 		Matches -&gt; narrow_matches_with_current_path(Matches)
 	end.
@@ -112,9 +113,9 @@ narrow_matches_with_current_path(Matches) -&gt;
 	CurrentPath = lists:reverse(wf_context:current_path()),
 	Matches1 = [lists:reverse(X) || X &lt;- Matches],
 	case narrow_matches_with_current_path(CurrentPath, Matches1, 1) of
-		[] -&gt; throw({no_matching_dom_paths, Matches});
+		[] -&gt; throw({dom_path_error, no_matching_paths});
 		[Match] -&gt; lists:reverse(Match);
-		Matches -&gt; throw({too_many_matching_dom_paths, Matches})
+		Matches -&gt; throw({dom_path_error, too_many_matching_paths})
 	end.
 	
 % Similar to find_matching_dom_path, except we stop when we narrow
@@ -124,7 +125,9 @@ narrow_matches_with_current_path(_, [], _) -&gt; [];
 narrow_matches_with_current_path(_, Matches, _) when length(Matches) == 1 -&gt; Matches;
 narrow_matches_with_current_path(Path, Matches, Pos) -&gt;
 	Part = lists:nth(Pos, Path),
-	F = fun(X) -&gt; Part == lists:nth(Pos, X) end,
+	F = fun(X) -&gt; 
+	    Pos =&lt; length(X) andalso Part == lists:nth(Pos, X) 
+	end,
 	Matches1 = lists:filter(F, Matches),
 	narrow_matches_with_current_path(Path, Matches1, Pos + 1).
 	</diff>
      <filename>src/lib/wf_path.erl</filename>
    </modified>
    <modified>
      <diff>@@ -65,9 +65,24 @@ render_action(Action) when is_tuple(Action) -&gt;
 			TriggerPath = wf:coalesce([Base#actionbase.trigger, TargetPath, OldPath]),
 
 			% Normalize the trigger and target...
+			TriggerPath1 = try
+			    wf_path:normalize_path(TriggerPath) 
+			catch 
+			    _Type1 : {dom_path_error, Err1} -&gt; 
+			        ?PRINT({dom_path_error, Err1, TriggerPath, Action}),
+			        [TriggerPath]
+			end,
+			TargetPath1 = try
+			    wf_path:normalize_path(TargetPath) 
+			catch 
+			    _Type2 : {dom_path_error, Err2} -&gt; 
+			        ?PRINT({dom_path_error, Err2, TargetPath, Action}),
+			        [TargetPath]
+			end,
+			
 			Base1 = Base#actionbase {
-				trigger = wf_path:normalize_path(TriggerPath),
-				target = TargetPath1 = wf_path:normalize_path(TargetPath)
+				trigger = TriggerPath1,
+				target = TargetPath1
 			},
 			Action1 = wf_utils:replace_with_base(Base1, Action),
 </diff>
      <filename>src/lib/wf_render_actions.erl</filename>
    </modified>
    <modified>
      <diff>@@ -112,6 +112,7 @@ temp_id() -&gt;
 	{_, _, C} = now(), 
 	&quot;temp&quot; ++ integer_to_list(C).
 
+
 is_temp_element(undefined) -&gt; true;
 is_temp_element([P]) -&gt; is_temp_element(P);
 is_temp_element(P) -&gt; </diff>
      <filename>src/lib/wf_render_elements.erl</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,10 @@ run() -&gt;
 				Response1:build_response()
 		end
 	catch Type : Error -&gt; 
-		?LOG(&quot;~p~n&quot;, [{error, Type, Error, erlang:get_stacktrace()}])
+		?LOG(&quot;~p~n&quot;, [{error, Type, Error, erlang:get_stacktrace()}]),
+		ErrResponse = Response:status_code(500),
+		ErrResponse1 = ErrResponse:data(&quot;Internal Server Error&quot;),
+		ErrResponse1:build_response()
 	end.
 
 run_catched() -&gt;</diff>
      <filename>src/wf_core.erl</filename>
    </modified>
    <modified>
      <diff>@@ -166,6 +166,7 @@ NitrogenClass.prototype.$do_system_event = function(eventContext) {
 	for (var key in this.$params) {
 		params += key + &quot;=&quot; + this.$params[key] + &quot;&amp;&quot;;
 	}
+	params += &quot;is_system_event=1&quot;
 
 	var n = this;
 
@@ -175,7 +176,9 @@ NitrogenClass.prototype.$do_system_event = function(eventContext) {
 		data: params,
 		dataType: 'text',
 		success: function(data, textStatus) {
+            var pc = n.$params[&quot;pageContext&quot;];
 			eval(data);
+            n.$set_param(&quot;pageContext&quot;, pc);
 		},
 		error: function(xmlHttpRequest, textStatus, errorThrown) {
 		}
@@ -229,9 +232,9 @@ NitrogenClass.prototype.$scan_elements = function(path, elements) {
 	for (var i=0; i&lt;elements.length; i++) {
 		var t = elements[i].id;
 		if (t == undefined) continue;
-		var pos = t.indexOf(path);
+		var pos = t.lastIndexOf(path);
 		if (pos == -1) continue;
-		if (t.indexOf(path) + path.length == t.length) {
+		if (pos + path.length == t.length) {
 			return elements[i];
 		}
 	}
@@ -278,8 +281,8 @@ NitrogenClass.prototype.$return_false = function(value, args) {
 	return false; 
 }
 
-NitrogenClass.prototype.$is_enter_key = function(event) {
-	return (event &amp;&amp; event.keyCode == 13);
+NitrogenClass.prototype.$is_key_code = function(event, keyCode) {
+	return (event &amp;&amp; event.keyCode == keyCode);
 }
 
 NitrogenClass.prototype.$go_next = function(controlID) {</diff>
      <filename>www/nitrogen.js</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>www/bert.js</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>9f9354be93b9a7210fa2c350af5f0e0bb17bc671</id>
    </parent>
    <parent>
      <id>4bcafe70acd6e51efdf932f4133db3433bde4c67</id>
    </parent>
  </parents>
  <author>
    <name>Rusty Klophaus</name>
    <email>rklophaus@gmail.com</email>
  </author>
  <url>http://github.com/rklophaus/nitrogen/commit/f500d64dcf41e18126e2d211b8f4aae55958b436</url>
  <id>f500d64dcf41e18126e2d211b8f4aae55958b436</id>
  <committed-date>2009-10-27T16:28:06-07:00</committed-date>
  <authored-date>2009-10-27T16:28:06-07:00</authored-date>
  <message>Merge branch 'experimental' of git@github.com:rklophaus/nitrogen into experimental

Conflicts:
	Nitrogen.tmproj</message>
  <tree>e34bf8a0c8bc80ba5274e40843d48334936d437e</tree>
  <committer>
    <name>Rusty Klophaus</name>
    <email>rklophaus@gmail.com</email>
  </committer>
</commit>
