diff --git a/examples/resource.rs b/examples/resource.rs
index 94c0ba0047ec464c692edf80089c3160952bf498..06847696f3d471ce2bdd028196c1e38a641f42d5 100644
--- a/examples/resource.rs
+++ b/examples/resource.rs
@@ -1,5 +1,4 @@
-//! Minimal example with zero tasks
-//#![deny(unsafe_code)]
+//! Example using shared resources
 // IMPORTANT always include this feature gate
 #![feature(proc_macro)]
 #![feature(used)]
@@ -11,7 +10,7 @@ extern crate stm32f413;
 
 #[macro_use]
 extern crate klee;
-use klee::k_abort;
+//use klee::k_abort;
 
 // import the procedural macro
 use rtfm::{app, Resource, Threshold};
@@ -46,6 +45,7 @@ app! {
     },
 }
 
+#[allow(non_snake_case)]
 fn exti1(t: &mut Threshold, EXTI1::Resources { X, mut Y }: EXTI1::Resources) {
     X.claim(t, |x, t1| {
         Y.claim_mut(t1, |y, _| {
@@ -58,6 +58,7 @@ fn exti1(t: &mut Threshold, EXTI1::Resources { X, mut Y }: EXTI1::Resources) {
     });
 }
 
+#[allow(non_snake_case)]
 fn exti2(t: &mut Threshold, mut r: EXTI2::Resources) {
     r.Y.claim_mut(t, |y, _| {
         if *y < 10 {
@@ -68,6 +69,7 @@ fn exti2(t: &mut Threshold, mut r: EXTI2::Resources) {
     });
 }
 
+#[allow(non_snake_case)]
 fn exti3(t: &mut Threshold, mut r: EXTI3::Resources) {
     r.X.claim_mut(t, |x, _| {
         *x += 1;
@@ -78,55 +80,435 @@ fn exti3(t: &mut Threshold, mut r: EXTI3::Resources) {
 #[allow(dead_code)]
 fn init(_p: init::Peripherals, _r: init::Resources) {}
 
-// extern crate cortex_m;
-// use cortex_m::register::basepri;
-
-// // for wcet should be autogenerated...
-
-// #[inline(never)]
-// #[no_mangle]
-// fn readbasepri() -> u8 {
-//     cortex_m::register::basepri::read()
-// }
-// #[inline(never)]
-// #[allow(non_snake_case)]
-// #[no_mangle]
-// fn stub_EXTI1() {
-//     unsafe { _EXTI1() };
-// }
-// #[inline(never)]
-// #[no_mangle]
-// #[allow(non_snake_case)]
-// fn stub_EXTI2() {
-//     unsafe { _EXTI2() };
-// }
-// #[inline(never)]
-// #[no_mangle]
-// #[allow(non_snake_case)]
-// fn stub_EXTI3() {
-//     unsafe {
-//         _EXTI3();
-//     }
-// }
-
-// The idle loop.
-//
-// This runs after `init` and has a priority of 0. All tasks can preempt this
-// function. This function can never return so it must contain some sort of
-// endless loop.
 #[inline(never)]
+#[allow(dead_code)]
 fn idle() -> ! {
-    // readbasepri();
-    // stub_EXTI1(); // here to provide stub for gdb
-    // stub_EXTI2(); // here to provide stub for gdb
-    // stub_EXTI3(); // here to provide stub for gdb
-
     loop {
         rtfm::nop();
     }
 }
 
+// Static code analysis
+// In this lab we will study how a Rust RTFM application can be
+// statically analysed.
+//
+// The application has three tasks EXTI1, EXTI2 and EXTI3,
+// with associated priorites 1 (lowest), 3 (highest), and 2 (mid).
+//
+// Assignment 1.
+// Build the application for KLEE analysis.
+// > xargo build --example resource  --features klee_mode --target x86_64-unknown-linux-gnu
+//
+// Start the KLEE docker
+// > docker run --rm --user $(id -u):$(id -g) -v $PWD/target/x86_64-unknown-linux-gnu/debug/examples:/mnt -w /mnt -it afoht/llvm-klee-4 /bin/bash
+//
+// Notice, in this case we have compiled in dev/debug mode, such to avoid optimzation
+// of the generated LLVM IR code. Thus the docker should run in the `.../debug/..` folder.
+//
+// Now run KLEE in the docker.
+// > klee resource-*.bc
+// KLEE: WARNING: executable has module level assembly (ignoring)
+// KLEE: ERROR: /home/pln/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.3.13/src/lang_items.rs:1: abort failure
+// KLEE: NOTE: now ignoring this error at this location
+
+// KLEE: done: total instructions = 11575
+// KLEE: done: completed paths = 25
+// KLEE: done: generated tests = 16
+//
+// When compiled with the --features klee_mode, resources are treated as symbolic.
+// Investigate the output files (in `klee-last`). Use `ktest-tool` to examine the tests.
+// The file `klee/tasks.txt` gives the order of tasks, it may vary for each run.
+// ```
+// // autogenerated file
+// ["EXTI1", "EXTI2", "EXTI3"]
+// ```
+//
+// How many tests were generated for task EXIT1?
+// ** your answer here **
+// Why that many, (look at the code and the generted tests).
+// ** your answer here **
+//
+// How many tests were generated for task EXIT2?
+// ** your answer here **
+// Why that many, (look at the code and the generted tests).
+// ** your answer here **
+//
+// How many tests were generated for task EXIT3?
+// ** your answer here **
+// Why that many, (look at the code and the generted tests).
+// ** your answer here **
+//
+// (There will be one additional "dymmy" test for testing "no task".)
+//
+// Now identify the cause of generated error.
+// > more klee-last/*.abort.err
+//
+// Find the error on the source code and fix it.
+// Hint, use *wrapping arithmetics*.
+//
+// Repeat the code generation, run KLEE agian and fix errors until
+// no more errors are found.
+//
+// How many errors were identified?
+// ** your answer here **
+//
+// For one of the arithmetic operations, no error was found.
+// Explain why this is no error.
+// ** your answer here **
+//
+// Why didn't KLEE report all the errors initially?
+// Scroll back and compare the stack traces of the generated errors.
+// Hint, for each line in the code KLEE will spot ONE error.
+// ** your answer here **
+//
+// Assignment 2.
+// KLEE has now generated tests covering EACH feasible path for EACH task.
+// Now we will analyse the exection time for each such test.
+//
+// In order to do that comiple your application.
+// > xargo build --example resource --release --features wcet_bkpt --target thumbv7em-none-eabihf
+//
+// We build in --release for optimizing the performance.
+// The --features wcet_bkpt will insert a `bkpt` instruction on LOCK ond UNLOCK of
+// of each resource. This allows you to monitor the number of clock cyckles using gdb.
+//
+// Start gdb.
+// > arm-none-eabi-gdb -x gdbinit_manual target/thumbv7em-none-eabihf/release/examples/resource
+//
+// The `gdbinit_manual` has the following content.
+// ```
+// target remote :3333
+// mon restet halt
+// load
+// tb main
+// continue
+//
+// Line by line it
+// - connects to the target (the MCU)
+// - resets the MCU
+// - loads the binary, in this case set to target/thumbv7em-none-eabihf/release/examples/resource
+// - sets a temporary breakpoint to `main`
+// - continues executing until `main` is reached.
+//
+// At the point the MCU hits `main` you will be promted to continue working <return> or quit
+// press <return>
+//
+// Now you can inspect where the processor halted.
+// >  (gdb) list
+// 560                 // be executed *before* enabling the FPU and that would generate an
+// 561                 // exception
+// 562                 #[inline(never)]
+// 563                 fn main() {
+// 564                     unsafe {
+// 565                         ::main(0, ::core::ptr::null());
+// 566                     }
+// 567                 }
+// 568
+// 569                 main()
+//
+// As you see this is not part of your program, rather it originates from the library startup code.
+//
+// This is perfect, now the MCU is initiated and under your control.
+//
+// At this point the memory (resources), holds their initial values from the
+// your application (this was set by the library code prior to hitting main).
+// You can inspect the global reasources (they are prepended by `_`).
+//
+// (gdb) p resource::_X
+// $1 = 0
+// (gdb) p resource::_Y
+// $2 = 0
+//
+// Before calling our tasks we need to enable the debug timer (cycle counter in the DWT unit of the MCU).
+//
+// (gdb) mon mww 0xe0001000 1
+//
+// and set the counter value to 0
+//
+// (gdb) mon mww 0xe0001004 0
+//
+// Now we can call the task(s). Lets start easy with EXTI3.
+// (gdb) call stub_EXTI3()
+// (gdb) mon mrw 0xe0001004
+// 9
+//
+// Wow, it took only 9 clock cycles to run the complete task!!!!
+// (Compare to a threaded OS that would require several 100 clock cycles to start a thread/task)
+//
+// But hey, where did my claim go? Wasn't I supposed to hit a breakpoint when claiming the resource?
+// (In this case the resource X)
+// Well Rust RTFM is smart enough to know that you are already at sufficient threshold (priority)
+// in order to grant you the resource dircectly. Let us look at the code.
+//
+// (gdb) disassemble stub_EXTI3
+// Dump of assembler code for function stub_EXTI3:
+//    0x08000268 <+0>:     movw    r0, #0
+//    0x0800026c <+4>:     movt    r0, #8192       ; 0x2000
+//    0x08000270 <+8>:     ldr     r1, [r0, #0]
+//    0x08000272 <+10>:    adds    r1, #1
+//    0x08000274 <+12>:    str     r1, [r0, #0]
+//    0x08000276 <+14>:    bx      lr
+// End of assembler dump.
+//
+// Here you go, cannot be simpler that this, it
+// - sets up the address to X in r0
+// - reads the old value
+// - adds 1 (wrapping arithmetics)
+// - stores the new value in X
+// - it returns
+// (On Cortex M functions and inerrupt handlers are essentially treated the same way)
+//
+// So now you can check the value of X. See above...
+// ++ your answer here **
+//
+// Now let us turn to EXTI2.
+// (gdb) mon mww 0xe0001004 0
+// (gdb) call stub_EXTI2()
+// (gdb) mon mrw 0xe0001004
+// 13
+//
+// Also in this case we see that the resource (Y) was granted without overhead
+// The code took a few additional clock cycles (its contians a condition, right).
+// Figure out which path was triggered by this test.
+// ** your answer here **
+//
+// Now figure out how to test the other branch
+// you can use
+// (gdb) set resource::_Y=...
+// to set a value in memory
+//
+// Make a call to the `stub_EXTI2()` with the set value of `_Y`.
+// How many clock cycles did you get (rember to set the counter to 0 before calling)
+// ** your answer here **
+//
+// Check the nwe value of `_Y`.
+// ** your answer here **
+//
+// Hint, if done correctly, you should have the same number of cycles for both paths.
+// Ok, so the cycle count was the same ;)
+// How so, lets have a look at the generated assembly.
+//
+//  (gdb) disassemble stub_EXTI2
+// Dump of assembler code for function stub_EXTI2:
+//    0x080002aa <+0>:     movw    r0, #0
+//    0x080002ae <+4>:     mov.w   r2, #4294967295 ; 0xffffffff
+//    0x080002b2 <+8>:     movt    r0, #8192       ; 0x2000
+//    0x080002b6 <+12>:    ldr     r1, [r0, #4]
+//    0x080002b8 <+14>:    cmp     r1, #10
+//    0x080002ba <+16>:    it      cc
+//    0x080002bc <+18>:    movcc   r2, #1
+//    0x080002be <+20>:    add     r1, r2
+//    0x080002c0 <+22>:    str     r1, [r0, #4]
+//    0x080002c2 <+24>:    bx      lr
+// End of assembler dump.
+//
+// This one is a bit harder to understand.
+// What it does essentially is to store -1 in r2
+// and conditionally overwrite the r2 by a 1 if `Y < 10`
+// and then add r2 to r1 (the current value of `Y`)
+// and update `Y` to r1.
+//
+// So this is beautiful, the COSTLY branch is replaced by a CHEAP
+// condtitonal assigmnet `movcc`.
+// You can read more on this on
+// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABEHFEF.html
+//
+// Ok, back to the program...
+// Now recall the KLEE generated test cases.
+// Spot the ones regarding EXTI2.
+// What assignments would KLEE suggest to `Y` to test both paths.
+// ** your answers here **
+//
+// So, your test assignments or the ones from KLEE, which ones is better?
+// ** your answer here **
+
+// (We will return to optimising test cases later... so put this on your mental stack :)
+//
+// Now lets have a look at the tricky one EXTI1.
+// (gdb) mon mww 0xe0001004 0
+// (gdb) call stub_EXTI1()
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// cortex_m_rtfm::claim (ceiling=2, _nvic_prio_bits=4, data=<optimized out>, t=<optimized out>, f=...)
+//     at /home/pln/klee/cortex-m-rtfm/src/lib.rs:167
+// 167                             bkpt();
+// The program being debugged was signaled while in a function called from GDB.
+// GDB remains in the frame where the signal was received.
+// To change this behavior use "set unwindonsignal on".
+// Evaluation of the expression containing the function
+// (stub_EXTI1) will be abandoned.
+// When the function is done executing, GDB will silently stop.
+//
+// So what is happening here is that it runs into the (first) brkp intstruction (LOCK `X`).
+// You may ignore the verbose output at this point....
+//
+// Run
+// (gdb) mon mrw 0xe0001004
+// 15
+//
+// So all in all it took 15 cycles to get there, `claim X`.
+// We can look at the code causing the `bkpt`
+// (gdb) list
+// 162                         }
+// 163
+// 164                         // wcet_bkpt mode
+// 165                         // put breakpoint at raise ceiling, for tracing execution time
+// 166                         if cfg!(feature = "wcet_bkpt") {
+// 167                             bkpt();
+// 168                         }
+//
+// That makes sense, we are in the RTFM library handling the `claim X`
+// (gdb) c
+// Continuing.
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// cortex_m_rtfm::claim (ceiling=3, _nvic_prio_bits=4, data=<optimized out>, t=<optimized out>, f=...)
+//     at /home/pln/klee/cortex-m-rtfm/src/lib.rs:167
+// 167                             bkpt();
+// (gdb) mon mrw 0xe0001004
+// 19
+//
+// So after 19 clock cycles we claim `Y`
+//
+// Now lets have a look at the generated assembly.
+// (gdb) disassemble
+// ...
+//    0x080002f6 <+4>:     bcs.n   0x8000334 <resource::<impl rtfm_core::Resource for resource::EXTI1::X>::claim+66>
+//    0x080002f8 <+6>:     movs    r1, #224        ; 0xe0
+//    0x080002fa <+8>:     movs    r2, #208        ; 0xd0
+//    0x080002fc <+10>:    mrs     r12, BASEPRI
+//    0x08000300 <+14>:    msr     BASEPRI, r1
+//    0x08000304 <+18>:    bkpt    0x0000
+//    0x08000306 <+20>:    mrs     r1, BASEPRI
+//    0x0800030a <+24>:    msr     BASEPRI, r2
+//    0x0800030e <+28>:    movw    r2, #0
+// => 0x08000312 <+32>:    bkpt    0x0000
+//    0x08000314 <+34>:    movt    r2, #8192       ; 0x2000
+//    0x08000318 <+38>:    ldr     r3, [r2, #0]
+//    0x0800031a <+40>:    subs    r0, r3, #1
+//    0x0800031c <+42>:    cmp     r0, #8
+//    0x0800031e <+44>:    ittt    ls
+//    0x08000320 <+46>:    ldrls   r0, [r2, #4]
+//    0x08000322 <+48>:    addls   r0, r3
+//    0x08000324 <+50>:    strls   r0, [r2, #4]
+//    0x08000326 <+52>:    bkpt    0x0000
+//    0x08000328 <+54>:    msr     BASEPRI, r1
+// ...
+//
+// We are now inside the critital sections of both X and Y and have access to both resources for the loop.
+// (gdb) c
+// Continuing.
+//
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// cortex_m_rtfm::claim (ceiling=3, _nvic_prio_bits=4, data=<optimized out>, t=<optimized out>, f=...)
+//     at /home/pln/klee/cortex-m-rtfm/src/lib.rs:181
+//
+// We are now releasing `Y`.
+// (gdb) mon mrw 0xe0001004
+// 29
+//
+// How long (in cycles) was the critical section on `Y`?
+// ** your answer here **
+
+// (gdb) disassemble
+// ...
+//    0x08000322 <+48>:    addls   r0, r3
+//    0x08000324 <+50>:    strls   r0, [r2, #4]
+// => 0x08000326 <+52>:    bkpt    0x0000
+//    0x08000328 <+54>:    msr     BASEPRI, r1
+// ...
+//
+// Let us continue
+// (gdb) c
+// Continuing.
+
+// Program received signal SIGTRAP, Trace/breakpoint trap.
+// cortex_m_rtfm::claim (ceiling=2, _nvic_prio_bits=4, data=<optimized out>, t=<optimized out>, f=...)
+//     at /home/pln/klee/cortex-m-rtfm/src/lib.rs:181
+// 181                             bkpt();
+//
+// (gdb) mon mrw 0xe0001004
+// 30
+//
+// How long (in cycles) was the critical section on `X`?
+// ** your answer here **
+//
+// (gdb) disassemble
+// ...
+//    0x08000326 <+52>:    bkpt    0x0000
+//    0x08000328 <+54>:    msr     BASEPRI, r1
+// => 0x0800032c <+58>:    bkpt    0x0000
+//    0x0800032e <+60>:    msr     BASEPRI, r12
+//    0x08000332 <+64>:    bx      lr
+//
+// At this point we can contiue
+// (gdb) c
+// Continuing.
+// EXTI1 has now run to completion.
+//
+// What was the total excecution time for EXTI1?
+// ** your answer here **
+//
+// What is the value of the resouce X?
+// ** your answer here **
+//
+// Just by looking at the code, what would the worst case assignment of X be?
+// I.e., the assingnment of `X' that gives the worst case execution time.
+// ** your answer here **
+//
+// Measure that execution time. What did you get.
+// ** your answer here **
+//
+// Your answer might blow your mind!!! How the heck is that even possible?
+//
+// At this point you should find that the worst case time stays the same ...
+//
+// Well, this one is not due to RTFM, its due to Rust and the cleverness of LLVM.
+// What it does is that it figures out that we actually incleas Y, by the value of X.
+// So the loop is all gone, optimized out, and replaced by a simple addition.
+//
+// Now lets look at best case execution time.
+// Figure out an assignment of X, that might actually reduce the execution time.
+// ** your answer here **
+//
+// Redo the experiment with this value. How many clock cycles did you get?
+// ** your answer here **
+//
+// Assignment 3.
+// In assignment 2 we analysed EXTI1
+// We found that for the examples, Rust RTFM was able to generate extremely efficient
+// implementations, replacing branching with contdiditonal assignments and
+// even remove comlete loops.
+//
+// Now lets have a look at using optimized LLVM and how it affects the number of tests.
+// > xargo build --example resource --release --features klee_mode --target x86_64-unknown-linux-gnu
+//
+// and now start a docker for the optimized build
+// > docker run --rm --user $(id -u):$(id -g) -v $PWD/target/x86_64-unknown-linux-gnu/release/examples:/mnt -w /mnt -it afoht/llvm-klee-4 /bin/bash
+//
+// and in the docker run
+// > klee resource*.bc
+//
+// Look at the generated tests.
+// Motivate for each of the 5 test cases, which one it matches of the hand generated tests from Assignment 2.
+// ** your asnwers (5) here **
+//
+// Were the optimized tests sufficient to cover the execution time behavior.
+// ** your answer here **
+//
+// Can you come up with a case where --release mode based analysis would miss cricital cases.
+// ** your answer here, --- actually a research question, we will discuss in class --- **
+//
+// On a side note.
+// Rust in --release mode makes the job for KLEE much easier. Look the number of instuctions carried out.
+// In dev/debug you had som 10 000 instuctions executed for generating the test cases.
+// In --relesase you had 34!!!!!
+//
+// This vastly improves on the performance of analysis, allowing larger applications to be scrutenized.
+// The code we looked at here was by intention simple (to facilitate inspection).
+// However, the code is NOT trivial, under the hood it utilizes advanced language features, such as
+// closures and intence use of abstractions, such as Traits/genecics etc. It indeed covers a large
+// degree of the Rust, for which it demonstrates that our approach to based program analysis
+// actually works.
 //
-//0x80001dc        0x80001dc <cortex_m_rt::reset_handler+4>
-//0x8000270        0x8000270 <resource::init>
-//0x8000284        0x8000284 <resource::idle+10>
+// For the future we intend the framework to cover the reading and writing to peripherals, and the
+// sequenced access to resources. In class we will further discuss current limitations, and
+// oportunitios to improvements.
diff --git a/macros/src/trans.rs b/macros/src/trans.rs
index 2c8ea462d59bcb1ced02a75d14232c59dd357f0f..e091bc0936ecf6611cef699f81c4a74fbf25b48b 100644
--- a/macros/src/trans.rs
+++ b/macros/src/trans.rs
@@ -670,7 +670,6 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
         let path = &task.path;
         let _tname = Ident::new(format!("_{}", tname));
-        let _stub_tname = Ident::new(format!("stub_{}", tname));
         let export_name = Lit::Str(tname.as_ref().to_owned(), StrStyle::Cooked);
         root.push(quote! {
             #[allow(non_snake_case)]
@@ -681,15 +680,22 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
 
                 f(#(#exprs,)*)
             }
-
-            #[inline(never)]
-            #[no_mangle]
-            #[allow(non_snake_case)]
-            fn #_stub_tname() {
-                unsafe { #_tname(); }
-            }
         });
 
+        if cfg!(feature = "wcet_bkpt") {
+            let _stub_tname = Ident::new(format!("stub_{}", tname));
+            root.push(quote! {
+                #[inline(never)]
+                #[allow(private_no_mangle_fns)]
+                #[no_mangle]
+                #[allow(non_snake_case)]
+                fn #_stub_tname() {
+                    #[allow(unsafe_code)]
+                    unsafe { #_tname(); }
+                }
+            });
+        }
+
         root.push(quote!{
             #[allow(non_snake_case)]
             #[allow(unsafe_code)]