diff --git a/BackupEssentials/Backup/BackupReport.cs b/BackupEssentials/Backup/BackupReport.cs
new file mode 100644
index 0000000..5c1986f
--- /dev/null
+++ b/BackupEssentials/Backup/BackupReport.cs
@@ -0,0 +1,81 @@
+using BackupEssentials.Backup.IO;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace BackupEssentials.Backup{
+    class BackupReport{
+        private readonly string _plain;
+        private string _parsed;
+
+        public string Report {
+            get {
+                if (_parsed == null){
+                    StringBuilder build = new StringBuilder(16+(int)Math.Floor(_plain.Length*1.5D));
+
+                    foreach(string line in SplitByLine(_plain)){
+                        if (line.Length == 0)continue;
+
+                        if (line[0] == 'I')build.Append(line.Substring(1)).Append(Environment.NewLine);
+                        else if (line[0] == 'A' && line.Length > 3)build.Append(GetFullNameAction(line[1])).Append(' ').Append(GetFullNameType(line[2])).Append(' ').Append(line.Substring(3)).Append(Environment.NewLine);
+                    }
+
+                    _parsed = build.ToString();
+                }
+
+                return _parsed;
+            }
+        }
+
+        private BackupReport(string report){
+            this._plain = report;
+        }
+
+        public override string ToString(){
+            return Report;
+        }
+
+        public class Builder{
+            private StringBuilder Build = new StringBuilder(256);
+
+            public void Add(IOAction action, IOType type, string path){
+                Build.Append('A').Append(GetShortName(action)).Append(GetShortName(type)).Append(path).Append(Environment.NewLine);
+            }
+
+            public void Add(string message){
+                Build.Append('I').Append(message).Append(Environment.NewLine);
+            }
+
+            public BackupReport Finish(){
+                return new BackupReport(Build.ToString());
+            }
+        }
+
+        private static char GetShortName(IOAction action){
+            return action == IOAction.Create ? 'C' : action == IOAction.Delete ? 'D' : action == IOAction.Replace ? 'R' : '?';
+        }
+
+        private static string GetFullNameAction(char key){
+            return key == 'C' ? "Added" : key == 'D' ? "Deleted" : key == 'R' ? "Updated" : "(unknown action)";
+        }
+
+        private static char GetShortName(IOType type){
+            return type == IOType.File ? 'F' : type == IOType.Directory ? 'D' : '?';
+        }
+
+        private static string GetFullNameType(char key){
+            return key == 'F' ? "File" : key == 'D' ? "Folder" : "(unknown type)";
+        }
+
+        private static IEnumerable<string> SplitByLine(string str){
+            using(StringReader reader = new StringReader(str)){
+                string line;
+
+                while((line = reader.ReadLine()) != null){
+                    yield return line;
+                }
+            }
+        }
+    }
+}
diff --git a/BackupEssentials/Backup/BackupRunner.cs b/BackupEssentials/Backup/BackupRunner.cs
index df0ed35..c6df9c7 100644
--- a/BackupEssentials/Backup/BackupRunner.cs
+++ b/BackupEssentials/Backup/BackupRunner.cs
@@ -1,10 +1,13 @@
-using BackupEssentials.Utils;
+using BackupEssentials.Backup.IO;
+using BackupEssentials.Utils;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
+using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Text;
 
 namespace BackupEssentials.Backup{
     public class BackupRunner{
@@ -101,6 +104,19 @@ namespace BackupEssentials.Backup{
             int totalActions = actions.Count, attempts = 10;
             string path;
 
+            BackupReport.Builder reportBuilder = new BackupReport.Builder();
+            reportBuilder.Add("= Preparing backup =");
+            reportBuilder.Add("Source: "+src);
+            reportBuilder.Add("Destination: "+destFolder);
+            reportBuilder.Add("Date: "+DateTime.Now.ToString("d")+" "+DateTime.Now.ToString("t"));
+            reportBuilder.Add("");
+            reportBuilder.Add("= Files and folders =");
+            reportBuilder.Add("Added: "+actions.Count((entry) => entry.Action == IOAction.Create));
+            reportBuilder.Add("Updated: "+actions.Count((entry) => entry.Action == IOAction.Replace));
+            reportBuilder.Add("Deleted: "+actions.Count((entry) => entry.Action == IOAction.Delete));
+            reportBuilder.Add("");
+            reportBuilder.Add("= Starting backup =");
+
             while(actions.Count > 0 && --attempts > 0){
                 for(int index = 0; index < actions.Count; index++){
                     IOActionEntry entry = actions[index];
@@ -129,7 +145,7 @@ namespace BackupEssentials.Backup{
                         }
                         
                         indexesToRemove.Add(index-indexesToRemove.Count); // goes from 0 to actions.Count, removing each index will move the structure
-                        Debug.WriteLine("Finished: "+entry.ToString());
+                        reportBuilder.Add(entry.Action,entry.Type,entry.RelativePath);
 
                         worker.ReportProgress((int)Math.Ceiling(((totalActions-actions.Count+indexesToRemove.Count)*100D)/totalActions));
                         if (worker.CancellationPending)break;
@@ -139,22 +155,25 @@ namespace BackupEssentials.Backup{
                         // TODO handle special exceptions (security etc)
                     }
 
-                    if (worker.CancellationPending)throw new Exception("Backup canceled.");
+                    if (worker.CancellationPending){
+                        reportBuilder.Add("= Backup canceled =");
+                        e.Result = reportBuilder.Finish();
+                        throw new Exception("Backup canceled.");
+                    }
                 }
 
                 foreach(int index in indexesToRemove)actions.RemoveAt(index);
                 indexesToRemove.Clear();
             }
 
-            if (attempts == 0)throw new Exception("Backup failed: ran out of attempts.");
-        }
+            if (attempts == 0){
+                reportBuilder.Add("= Backup failed (out of attempts) =");
+                e.Result = reportBuilder.Finish();
+                throw new Exception("Backup failed: ran out of attempts.");
+            }
 
-        private enum IOType{
-            None, File, Directory
-        }
-
-        private enum IOAction{
-            None, Create, Replace, Delete
+            reportBuilder.Add("= Backup finished =");
+            e.Result = reportBuilder.Finish();
         }
 
         private class IOEntry{
diff --git a/BackupEssentials/Backup/IO/IOAction.cs b/BackupEssentials/Backup/IO/IOAction.cs
new file mode 100644
index 0000000..165f8df
--- /dev/null
+++ b/BackupEssentials/Backup/IO/IOAction.cs
@@ -0,0 +1,5 @@
+namespace BackupEssentials.Backup.IO{
+    enum IOAction{
+        None, Create, Replace, Delete
+    }
+}
diff --git a/BackupEssentials/Backup/IO/IOType.cs b/BackupEssentials/Backup/IO/IOType.cs
new file mode 100644
index 0000000..be2e6b3
--- /dev/null
+++ b/BackupEssentials/Backup/IO/IOType.cs
@@ -0,0 +1,5 @@
+namespace BackupEssentials.Backup.IO{
+    enum IOType{
+        None, File, Directory
+    }
+}
diff --git a/BackupEssentials/BackupEssentials.csproj b/BackupEssentials/BackupEssentials.csproj
index e480164..2f73f49 100644
--- a/BackupEssentials/BackupEssentials.csproj
+++ b/BackupEssentials/BackupEssentials.csproj
@@ -83,9 +83,12 @@
       <DependentUpon>BackupWindow.xaml</DependentUpon>
     </Compile>
     <Compile Include="Backup\BackupLocation.cs" />
+    <Compile Include="Backup\BackupReport.cs" />
     <Compile Include="Backup\BackupRunner.cs" />
     <Compile Include="Backup\DataStorage.cs" />
     <Compile Include="Backup\ExplorerIntegration.cs" />
+    <Compile Include="Backup\IO\IOAction.cs" />
+    <Compile Include="Backup\IO\IOType.cs" />
     <Compile Include="Pages\About.xaml.cs">
       <DependentUpon>About.xaml</DependentUpon>
     </Compile>
diff --git a/BackupEssentials/BackupWindow.xaml.cs b/BackupEssentials/BackupWindow.xaml.cs
index 4d40110..cdee0c4 100644
--- a/BackupEssentials/BackupWindow.xaml.cs
+++ b/BackupEssentials/BackupWindow.xaml.cs
@@ -10,6 +10,7 @@ namespace BackupEssentials{
     public partial class BackupWindow : Window{
         private BackupRunner Runner;
         private int ActionCount;
+        private BackupReport Report;
         private DispatcherTimer CloseTimer;
 
         public BackupWindow(BackupRunner runner){
@@ -48,6 +49,9 @@ namespace BackupEssentials{
             Runner = null;
             ButtonShowReport.IsEnabled = true;
             ButtonEnd.Content = "Close";
+            Report = e.Result as BackupReport;
+
+            Debug.WriteLine(Report.Report);
 
             if (e.Error != null){
                 LabelInfo.Content = e.Error.Message;