diff --git a/srp_analysis/src/aux.rs b/srp_analysis/src/aux.rs
index c6bd07425e521cddd0dda6ba7c427aced089af35..e701c35674a1ef2b0af2f76abf5aaabf3d9d9e01 100644
--- a/srp_analysis/src/aux.rs
+++ b/srp_analysis/src/aux.rs
@@ -11,6 +11,10 @@ pub struct TaskTimes {
     pub i: u32  // Preumtion time
 }
 
+pub fn task_load(task: &Task) -> f32 {
+    return task.get_wcet() as f32 / task.inter_arrival as f32;
+}
+
 /// Returns the total load factor, L(t) = C(t) / A(t) (Where C(t) is WCET and A(t) is the inter-arrival time of the task).
 /// 
 /// See: https://gitlab.henriktjader.com/pln/klee_tutorial/-/blob/master/HOME_EXAM.md#L85
@@ -22,7 +26,7 @@ pub struct TaskTimes {
 pub fn total_cpu_load(tasks: &Vec<Task>) -> f32 {
     let mut total_l: f32 = 0.0;
     for task in tasks {
-        total_l += task.get_wcet() as f32 / task.inter_arrival as f32;
+        total_l += task_load(&task);
     }
     return total_l;
 }
@@ -150,7 +154,7 @@ pub fn preemption_time(task: &Task, task_set: &Tasks, bp_approx: bool) -> Result
         let wcet = task.get_wcet();
         let block_t = blocking_time(&task, &task_set);
 
-        // Give us the first estimate
+        // Give us the first estimate (initial condition)
         let mut r_estimate = wcet + block_t;
 
         loop {
@@ -159,7 +163,7 @@ pub fn preemption_time(task: &Task, task_set: &Tasks, bp_approx: bool) -> Result
 
             if prev_r_est > task.deadline {
                 // Our busy period is deviating, break it of
-                return Err("The busy period deviated....")
+                return Err("The task is not scheduable given the current task set.")
             }
 
             let mut preemp_t_est = 0;
diff --git a/srp_analysis/src/main.rs b/srp_analysis/src/main.rs
index b62a48019b5d857ece6902386134af9535c0fb38..9282f2a298fc465a3293c4d9f645f420163e2487 100644
--- a/srp_analysis/src/main.rs
+++ b/srp_analysis/src/main.rs
@@ -1,15 +1,40 @@
 pub mod common;
 pub mod aux;
 
+use std::fs;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::Path;
+
 use std::path::PathBuf;
 use structopt::StructOpt;
+use structopt::clap::arg_enum;
 
 use common::*;
 use aux::*;
 
+/*
+enum Example {
+    POSSIBLE,
+    IMPOSSIBLE
+}*/
+
+arg_enum! {
+    #[derive(Debug)]
+    enum Example {
+        POSSIBLE,
+        IMPOSSIBLE
+    }
+}
+
 /// A basic example
 #[derive(StructOpt, Debug)]
-#[structopt(name = "srp_analysis", about ="asdasdasdasd")]
+#[structopt(name = "srp_analysis", about ="
+Running
+cargo run -- --generate_example -o example.json
+cargo run -- --approximate -i example.json
+cargo run -- --help
+")]
 struct Opt {
     // A flag, true if used in the command line. Note doc comment will
     // be used for the help message of the flag. The name of the
@@ -18,49 +43,175 @@ struct Opt {
     #[structopt(name = "approximate", long)]
     approx_bp: bool,
 
+    // The number of occurrences of the `v/verbose` flag
+    /// Verbose mode (-v, -vv, -vvv, etc.)
+    #[structopt(short, long, parse(from_occurrences))]
+    verbose: u8,
+
     /// Generate an example file
     #[structopt(long)] //
     generate: bool,
 
 
-
-
+    #[structopt(short = "ex", long = "example", possible_values = &Example::variants(), case_insensitive = true, default_value = "possible")]
+    example: Example,
 
     /// Output file for generated example
     #[structopt(short, long, parse(from_os_str))]
     output: Option<PathBuf>,
 
-    /// Output file for generated example
+    /// Input file for for task definition
     #[structopt(short, long, parse(from_os_str), required_unless = "generate")]
     input: Option<PathBuf>,
 
 }
-    
+    /*
+    // Genarate a certain example (schedulable, non-schedulable)
+    #[structopt(short = "ex", long = "example", default_value = "schedulable")]
+    example: Example,
+    */
 
-    // The number of occurrences of the `v/verbose` flag
-    /// Verbose mode (-v, -vv, -vvv, etc.)
-    //#[structopt(short, long, parse(from_occurrences))]
-    //verbose: u8,
+fn main() {
+    let exit_code = real_main();
+    std::process::exit(exit_code);
+}
+
+fn real_main() -> i32 {
+    let opt = Opt::from_args();
+    macro_rules! verbose_p {
+        ($format:expr, $s: expr, $verbose_lvl: expr) => { if opt.verbose >= $verbose_lvl { println!($format,$s) } }
+    }
+
+    verbose_p!("Parameters: {:?}", opt, 1);
+    if opt.generate {
+        let tasks = match opt.example {
+            Example::POSSIBLE => {
+                verbose_p!("{}", "Generating a schedulable task set", 1);
+                schedulable_task_set()
+            },
+            Example::IMPOSSIBLE => {
+                verbose_p!("{}", "Generating a non-schedulable task set", 1);
+                non_schedulable_task_set()
+            }
+        };
+
+        // Convert the task vector to a JSON string.
+        let serialized = serde_json::to_string(&tasks).unwrap();
+
+        if let Some(output_file) = opt.output {
+            let path = Path::new(&output_file);
+            let display = path.display();
+
+            // Code taken from: https://doc.rust-lang.org/rust-by-example/std_misc/file/create.html
+            // Open a file in write-only mode, returns `io::Result<File>`
+            let mut file = match File::create(&path) {
+                Err(why) => panic!("couldn't create {}: {}", display, why),
+                Ok(file) => file,
+            };
+
+            // Write the serialized data to `file`, returns `io::Result<()>`
+            match file.write_all(serialized.as_bytes()) {
+                Err(why) => panic!("couldn't write to {}: {}", display, why),
+                Ok(_) => println!("successfully wrote example data wrote to: {}", display),
+            }
+
+        } else {
+            println!("{}", serialized);
+        }
+
+        return 0;
+    }
+
+    let input_file = opt.input.unwrap(); // Let it panic, if it has reached this stage and panics we've fucked up our StructOpt config
     
-    /// Set speed
-    //#[structopt(short, long, default_value = "42")]
-    //speed: f64,
+    let serialized_data = fs::read_to_string(input_file).unwrap();
+    let tasks: Tasks = serde_json::from_str(&serialized_data).unwrap();
+    verbose_p!("Data from file: {}", serialized_data, 2);
 
-    // the long option will be translated by default to kebab case,
-    // i.e. `--nb-cars`.
-    /// Number of cars
-    //#[structopt(short = "c", long)]
-    //nb_cars: Option<i32>,
+    verbose_p!("Parsed data: {:?}", &tasks, 3);
 
-    /// admin_level to consider
-    //#[structopt(short, long)]
-    //level: Vec<String>,
+    let (ip, tr) = pre_analysis(&tasks);
 
-    /// Files to process
-    //#[structopt(name = "FILE", parse(from_os_str))]
-    //files: Vec<PathBuf>,
+    verbose_p!("ip: {:?}", ip, 1);
+    verbose_p!("tr: {:?}", tr, 1);
 
-fn main() {
+    match opt.approx_bp {
+        false  => {
+            println!("=== Running analysis (realistic) ===");
+            println!("Note: While running without approximation, busy period (Bp(t)) will be computed in relation to all other tasks.\n");
+        },
+        true => {
+            println!("=== Running analysis (approximation) ===");
+            println!("Note: While running with approximation, busy period (Bp(t)) will be defined as the deadline time (D(t)) of a task.\n");
+        }
+    }
+    println!("=== Task analysis: results ===");
+    for t in tasks.iter() {
+        println!("-> {:?}", &t.id);
+        match response_time(&t, &tasks, opt.approx_bp) {
+            Ok(re) => println!(":: Response time   = {:?}", re),
+            Err(_) => println!(":: Response time   = INCONC")
+        }
+        match preemption_time(&t, &tasks, opt.approx_bp) {
+            Ok(re) => println!(":: Preemption time = {:?}", re),
+            Err(_) => println!(":: Preemption time = INCONC")
+        }
+        /*
+        println!(":: Response time   (safe approx) = {:?}", response_time(&t, &tasks, true).unwrap());
+        println!(":: Preemption time (safe approx) = {:?}", preemption_time(&t, &tasks, true).unwrap());
+        match response_time(&t, &tasks, false) {
+            Ok(re) => println!(":: Response time   (realistic)   = {:?}", re),
+            Err(_) => println!(":: Response time   (realistic)   = INCONC")
+        }
+        match preemption_time(&t, &tasks, false) {
+            Ok(re) => println!(":: Preemption time (realistic)   = {:?}", re),
+            Err(_) => println!(":: Preemption time (realistic)   = INCONC")
+        }
+        */
+        println!(":: Blocking time   = {:?}", blocking_time(&t, &tasks));
+        println!(":: WCET            = {:?}", t.get_wcet());
+        println!("");
+    }
+
+    verbose_p!("Combined result = {:?}", times_as_vec(&tasks, false), 1);
+
+    println!("=== Schedulability analysis: results ===");
+    println!("-> Loadfactor");
+    for task in &tasks {
+        let t_load = task_load(&task);
+        if t_load <= 1.0 {
+            println!("{:?} : {:?} - OK", task.id, t_load);
+        } else {
+            println!("{:?} : {:?} - TO HIGH", task.id, t_load);
+        }
+    }
+    let l = total_cpu_load(&tasks);
+    if l <= 1.0 {
+        println!("Total loadfactor: {:?} - OK", l)
+    } else {
+        println!("Total loadfactor: {:?} - Task set not schedulable", l)
+    }
+    println!("-> response time, R(t) < D(t) ?");
+    let mut inconc: Vec<String> = vec![];
+    for task in &tasks {
+        match response_time(task, &tasks, opt.approx_bp) {
+            Ok(re) => println!("{:?} : {:?} - OK", task.id, re),
+            Err(_) => {
+                println!("{:?} : INCONC - R(t) >= {:?}", task.id, task.deadline);
+                inconc.push(task.id.clone().to_string());
+            }
+        }
+    }
+    if inconc.len() > 0 || l > 1.0 {
+        println!("--> Analysis result: Task set NOT schedulable <--");
+        return 1;
+    } else {
+        println!("--> Analysis result: Task set schedulable <--");
+        return 0;
+    }
+}
+
+fn schedulable_task_set() -> Tasks {
     let t1 = Task {
         id: "T1".to_string(),
         prio: 1,
@@ -123,75 +274,71 @@ fn main() {
         },
     };
 
-    // builds a vector of tasks t1, t2, t3
-    let tasks: Tasks = vec![t1, t2, t3];
-
-    // Example for running
-    // cargo run -- --generate_example -o hej.json
-    // cargo run -- -i hej.json --approximate
-    // cargo run -- --help
-
-    let opt = Opt::from_args();
-    //println!("{:?}", opt);
-    if opt.generate {
-
-        // Convert the Point to a JSON string.
-        let serialized = serde_json::to_string(&tasks).unwrap();
-
-        // Prints serialized = {"x":1,"y":2}
-        
-
-        if let Some(output_file) = opt.output {
-            println!("Saving example file to: {:?}", output_file);
-        } else {
-            println!("{}", serialized);
-        }
-        // Convert the JSON string back to a Point.
-        //let deserialized: [Task; 3] = serde_json::from_str(&serialized).unwrap();
-
-        // Prints deserialized = Point { x: 1, y: 2 }
-        //println!("deserialized = {:?}", deserialized);
-
-        return;
-    }
-
-    //let input_file = opt.input.unwrap(); // Let it panic, if it has reached this stage we've fucked up our StructOpt config
-
-    println!("tasks {:?}", &tasks);
-    // println!("tot_util {}", tot_util(&tasks));
-
-    let (ip, tr) = pre_analysis(&tasks);
-
-    println!("ip: {:?}", ip);
-    println!("tr: {:?}", tr);
-
-    let _approximate_bp = false;
+    return vec![t1,t2,t3];
+}
 
-    println!("=== Running analysis ===");
-    for t in tasks.iter() {
-        println!("-> {:?}", &t.id);
+fn non_schedulable_task_set() -> Tasks {
+    let t1 = Task {
+        id: "T1".to_string(),
+        prio: 1,
+        deadline: 100,
+        inter_arrival: 100,
+        trace: Trace {
+            id: "T1".to_string(),
+            start: 0,
+            end: 10,
+            inner: vec![],
+        },
+    };
 
-        println!(":: Response time   (safe approx) = {:?}", response_time(&t, &tasks, true).unwrap());
-        println!(":: Preemption time (safe approx) = {:?}", preemption_time(&t, &tasks, true).unwrap());
-        match response_time(&t, &tasks, false) {
-            Ok(re) => println!(":: Response time   (realistic)   = {:?}", re),
-            Err(_) => println!(":: Response time   (realistic)   = INCONC")
-        }
-        match preemption_time(&t, &tasks, false) {
-            Ok(re) => println!(":: Preemption time (realistic)   = {:?}", re),
-            Err(_) => println!(":: Preemption time (realistic)   = INCONC")
-        }
-        println!(":: Blocking time                 = {:?}", blocking_time(&t, &tasks));
-        println!(":: WCET                          = {:?}", t.get_wcet());
-        println!("");
-    }
+    let t2 = Task {
+        id: "T2".to_string(),
+        prio: 2,
+        deadline: 40,
+        inter_arrival: 100,
+        trace: Trace {
+            id: "T2".to_string(),
+            start: 0,
+            end: 30,
+            inner: vec![
+                Trace {
+                    id: "R1".to_string(),
+                    start: 10,
+                    end: 20,
+                    inner: vec![Trace {
+                        id: "R2".to_string(),
+                        start: 12,
+                        end: 16,
+                        inner: vec![],
+                    }],
+                },
+                Trace {
+                    id: "R1".to_string(),
+                    start: 22,
+                    end: 28,
+                    inner: vec![],
+                },
+            ],
+        },
+    };
 
-    println!("{:?}", times_as_vec(&tasks, false));
-    let l = total_cpu_load(&tasks);
-    if l <= 1.0 {
-        println!("Loadfactor: {:?} - OK", l)
-    } else {
-        println!("Loadfactor: {:?} - FAILED", l)
-    }
+    let t3 = Task {
+        id: "T3".to_string(),
+        prio: 3,
+        deadline: 50,
+        inter_arrival: 50,
+        trace: Trace {
+            id: "T3".to_string(),
+            start: 0,
+            end: 30,
+            inner: vec![Trace {
+                id: "R2".to_string(),
+                start: 10,
+                end: 20,
+                inner: vec![],
+            }],
+        },
+    };
 
-}
+    return vec![t1,t2,t3];
+}
\ No newline at end of file