diff --git a/generator/js_of_ast.ml b/generator/js_of_ast.ml
index 0d5bfca32c5bc066e8246177bc38d588797c2533..bd1e54265f2ab26cb4ea783411673ddeea110ae1 100644
--- a/generator/js_of_ast.ml
+++ b/generator/js_of_ast.ml
@@ -208,6 +208,15 @@ let ppf_module_wrap name content =
 
 
 
+
+(****************************************************************)
+(* FRESH ID NAMES *)
+
+let id_fresh prefix =
+  let r = ref 0 in
+  fun () -> (incr r; prefix ^ string_of_int !r)
+
+
 (****************************************************************)
 (* CONTEXTS *)
 
@@ -224,13 +233,13 @@ let ctx_initial =
 (****************************************************************)
 (* LOGGED CONSTRUCTORS *)
 
-let generate_logged_case spat binders ctx newctx sbody = ""
+let generate_logged_case spat binders ctx newctx sbody need_break = ""
   (* Note: if binders = [], then newctx = ctx *)
 
 (* generate_logged_case implement using
 [insertCaseCode(caseBody,bindings,ctx,newctx,sbody)]
-£4424;case(caseBody);codeOf(bindings);sbody
-case(caseBody); codeOf(bindings); newctx=ctx_push(ctx,bindings); logEvent(LINEOF(432423), "case", newctx);sbody
+£4424;case(caseBody);codeOf(bindings);sbody;break
+case(caseBody); codeOf(bindings); newctx=ctx_push(ctx,bindings); logEvent(LINEOF(432423), "case", newctx);sbody;break
 
 with help of
 
@@ -268,7 +277,25 @@ var x=e; var newctx=ctx_push(ctx,x,e); logEvent(LINEOF(432423), "let", ctx);sbod
 ----
 *)
 
+let generate_logged_enter arg_ids ctx newctx sbody = ""
+
+(*
 
+----
+function(x,y) {
+  [isnertEnterCode(bindings,ctx,newctx)]fdqfdsf
+  }
+
+TOKEN(432423);sbody
+
+var newctx = ctx_push(bindings);
+logEvent(LINEOF(432423), newctx, "enter");sbody
+----
+
+may reuse 
+    ppf_function args body
+
+*)
 
 
 
@@ -281,15 +308,22 @@ type dest =
   | Dest_ignore
   | Dest_return
   | Dest_assign of id
+  | Dest_inline
 
 let apply_dest dest sbody =
   match dest with
   | Dest_ignore -> sbody
   | Dest_return -> generate_logged_return ctx sbody
   | Dest_assign id -> Printf.sprintf "var %s = %s;" (ppf_ident id) sbody
+  | Dest_inline -> sbody
 
 (* LATER: pull out the "var" out of switch *)
 
+exception Not_good_for_dest_inline
+
+let reject_inline dest =
+  if dest = Dest_inline then raise Not_good_for_dest_inline
+
 
 (****************************************************************)
 (* TRANSLATION *)
@@ -330,68 +364,108 @@ and js_of_structure_item s =
   | Tstr_include    _  -> out_of_scope loc "includes"
   | Tstr_attribute  _  -> out_of_scope loc "attributes"
 
-and js_of_branch ctx dest b obj =
-  let spat, binders = js_of_pattern b.c_lhs obj in
+and js_of_branch ctx dest b eobj =
+  let spat, binders = js_of_pattern b.c_lhs eobj in
   let newctx = if binders = [] then ctx else ctx_fresh() in
   let sbody = js_of_expression newctx dest b.c_rhs in
-  generate_logged_case spat binders ctx newctx sbody 
-
+  let need_break = (dest <> Dest_return) in
+  generate_logged_case spat binders ctx newctx sbody need_break 
+     
+and js_of_expression_inline_or_wrap ctx e = 
+  try 
+    js_of_expression ctx Dest_inline e
+  with Not_good_for_dest_inline ->
+    js_of_expression_wrapped ctx e
+
+and js_of_expression_wrapped ctx e = (* dest = Dest_return *)
+  ppf_lambda_wrap (js_of_expression ctx Dest_return e)
 
 and js_of_expression ctx dest =
   let loc = e.exp_loc in
   match e.exp_desc with
+
   | Texp_ident (_, ident,  _) -> 
-      js_of_longident ident
+      let sexp = js_of_longident ident in
+      apply_dest dest sexp
+
   | Texp_constant c -> 
-      js_of_constant c
+      let sexp = js_of_constant c in
+      apply_dest dest sexp
+
   | Texp_let   (_, vb_l, e) ->
+    reject_inline dest;
     let (ids,sdecls) = List.split (List.map (fun vb -> show_value_binding ctx vb) @@ vb_l) in
     let sdecl = String.concat lin1 @@ sdecls in
     let newctx = ctx_fresh() in
     let sbody = js_of_expression newctx dest e in
-    generate_logged_let ids ctx newctx sdecl sbody
+    let sexp = generate_logged_let ids ctx newctx sdecl sbody in
+    apply_dest dest sexp
    
   | Texp_function (_, c :: [], Total) ->
     let rec explore pats e = match e.exp_desc with
       | Texp_function (_, c :: [], Total) ->
-        let p, e = c.c_lhs, c.c_rhs
-        in explore (p :: pats) e
+        let (p, e) = (c.c_lhs, c.c_rhs) in 
+        explore (p :: pats) e
       | _ ->
-        String.concat ", " @@ List.map ident_of_pat @@ List.rev @@ pats, js_of_expression e in
-    let args, body = explore [c.c_lhs] c.c_rhs
-    in ppf_function args body
+        List.map ident_of_pat @@ List.rev @@ pats, e 
+      in
+    let arg_ids, body = explore [c.c_lhs] c.c_rhs in
+    let newctx = ctx_fresh() in
+    let newdest = Dest_return in
+    let sbody = js_of_expression newctx newdest body in
+    let sexp = generate_logged_enter arg_ids ctx newctx sbody in
+    apply_dest dest sexp
+
   | Texp_apply (f, exp_l) ->
-     let sl' = exp_l
+     let sl' = exp_l  (* only used to know if infix *)
                |> List.map (fun (_, eo, _) -> match eo with 
                                               | None -> out_of_scope loc "optional apply arguments"
                                               | Some ei -> ei) in
-     let sl = exp_l
+     let sl_clean = exp_l
               |> List.map (fun (_, eo, _) -> match eo with 
-                                             | one -> out_of_scope loc "optional apply arguments" 
-                                             | Some ei -> js_of_expression ei) in
-    let se = js_of_expression f in
-    if is_infix f sl' && List.length exp_l = 2
-    then ppf_apply_infix se (List.hd sl) (List.hd (List.tl sl))
-    else ppf_apply se (String.concat ", " sl)
+                                             | None -> out_of_scope loc "optional apply arguments" 
+                                             | Some ei -> ei) in
+     let sl = sl_clean |> List.map (fun ei -> js_of_expression_inline_or_wrap ctx ei) in
+     let se = js_of_expression_inline_or_wrap ctx f in
+     let sexp = 
+        if is_infix f sl' && List.length exp_l = 2
+           then ppf_apply_infix se (List.hd sl) (List.hd (List.tl sl))
+           else ppf_apply se (String.concat ", " sl)
+        in
+     apply_dest dest sexp
 
   | Texp_match (exp, l, [], Total) ->
-     let se = js_of_expression exp in
-     let sb = String.concat "@," (List.map (fun x -> js_of_branch x se) l) in
+     reject_inline dest;
+     let (sintro, seobj) = 
+        match exp.exp_desc with
+        | Texp_ident (_, ident,  _) -> 
+            "", (js_of_longident ident)
+        | _ ->  (* generate  var id = sexp;  *)
+            let id = id_fresh "_switch_arg_" in
+            let sdecl = js_of_expression (Dest_assign id) ctx exp in
+            sdecl, id
+        in
+     let sb = String.concat "@," (List.map (fun b -> js_of_branch ctx dest b seobj) l) in
      let const = exp_type_is_constant exp in
-     ppf_match se sb const
+     let sexp = ppf_match se sb const in
+     apply_dest dest sexp
 
   | Texp_tuple (tl) -> 
-     ppf_tuple @@ show_list_f (fun exp -> js_of_expression exp) ", " tl
+     let sexp = ppf_tuple @@ show_list_f (fun exp -> js_of_expression_inline_or_wrap ctx exp) ", " tl in
+     apply_dest dest sexp
 
   | Texp_construct (_, cd, el) ->
     let name = cd.cstr_name in
-    if el = [] then (* Constructor has no parameters *)
-      if is_sbool name then name (* Special case true/false to their JS natives *)
-      else ppf_single_cstrs name
-    else (* Constructor has parameters *)
-      let expr_strs = List.map (fun exp -> js_of_expression exp) el in
-      let expanded_constructors = map_cstr_fields ~loc ppf_cstr cd expr_strs in
-      ppf_multiple_cstrs name (show_list ", " expanded_constructors)
+    let sexp =
+      if el = [] then (* Constructor has no parameters *)
+        if is_sbool name then name (* Special case true/false to their JS natives *)
+        else ppf_single_cstrs name
+      else (* Constructor has parameters *)
+        let expr_strs = List.map (fun exp -> js_of_expression_inline_or_wrap ctx exp) el in
+        let expanded_constructors = map_cstr_fields ~loc ppf_cstr cd expr_strs in
+        ppf_multiple_cstrs name (show_list ", " expanded_constructors)
+      in
+    apply_dest dest sexp
 
   | Texp_array      (exp_l)           -> ppf_array @@ show_list_f (fun exp -> js_of_expression exp) ", " exp_l
   | Texp_ifthenelse (e1, e2, None)    -> ppf_ifthen (js_of_expression e1) (js_of_expression e2)
@@ -435,7 +509,7 @@ and js_of_longident loc =
 
 and ident_of_pat pat = match pat.pat_desc with
   | Tpat_var (id, _) -> ppf_ident id
-  | Tpat_any         -> ""
+  | Tpat_any         -> id_fresh "_pat_any_"
   | _ -> error ~loc:pat.pat_loc "functions can't deconstruct values"
 
 (* returns the name bound and the code that assigns a value to this name *)
@@ -516,17 +590,6 @@ example:
   case               => bound variables + name of new ctx
 
 
-----
-function(x,y) {
-  [isnertEnterCode(bindings,ctx,newctx)]fdqfdsf
-  }
-
-TOKEN(432423);
-
-var newctx = ctx_push(bindings);
-logEvent(LINEOF(432423), newctx, "enter")
-----
-