Commits

Anonymous committed 012cb08 Merge

Merge

Comments (0)

Files changed (20)

header_hero/MainForm.Designer.cs

-namespace HeaderHero
-{
-    partial class MainForm
-    {
-        /// <summary>
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary>
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Windows Form Designer generated code
-
-        /// <summary>
-        /// Required method for Designer support - do not modify
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.components = new System.ComponentModel.Container();
-            this.menuBarMenuStrip = new System.Windows.Forms.MenuStrip();
-            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.newProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
-            this.openProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.closeProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.saveProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
-            this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.scanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.scanToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
-            this.label1 = new System.Windows.Forms.Label();
-            this.label2 = new System.Windows.Forms.Label();
-            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
-            this.includeDirsTextBox = new System.Windows.Forms.TextBox();
-            this.includeDirsContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
-            this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
-            this.label3 = new System.Windows.Forms.Label();
-            this.lastScanLabel = new System.Windows.Forms.Label();
-            this.projectDirsTextBox = new System.Windows.Forms.TextBox();
-            this.projectDirContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
-            this.addDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.cleanRescanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.menuBarMenuStrip.SuspendLayout();
-            this.tableLayoutPanel1.SuspendLayout();
-            this.includeDirsContextMenuStrip.SuspendLayout();
-            this.projectDirContextMenuStrip.SuspendLayout();
-            this.SuspendLayout();
-            // 
-            // menuBarMenuStrip
-            // 
-            this.menuBarMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.fileToolStripMenuItem,
-            this.scanToolStripMenuItem});
-            this.menuBarMenuStrip.Location = new System.Drawing.Point(0, 0);
-            this.menuBarMenuStrip.Name = "menuBarMenuStrip";
-            this.menuBarMenuStrip.Size = new System.Drawing.Size(605, 24);
-            this.menuBarMenuStrip.TabIndex = 0;
-            this.menuBarMenuStrip.Text = "menuStrip1";
-            // 
-            // fileToolStripMenuItem
-            // 
-            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.newProjectToolStripMenuItem,
-            this.toolStripMenuItem1,
-            this.openProjectToolStripMenuItem,
-            this.closeProjectToolStripMenuItem,
-            this.saveProjectToolStripMenuItem,
-            this.toolStripMenuItem2,
-            this.quitToolStripMenuItem});
-            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
-            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
-            this.fileToolStripMenuItem.Text = "File";
-            // 
-            // newProjectToolStripMenuItem
-            // 
-            this.newProjectToolStripMenuItem.Name = "newProjectToolStripMenuItem";
-            this.newProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
-            this.newProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
-            this.newProjectToolStripMenuItem.Text = "New Project";
-            this.newProjectToolStripMenuItem.Click += new System.EventHandler(this.newProjectToolStripMenuItem_Click);
-            // 
-            // toolStripMenuItem1
-            // 
-            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
-            this.toolStripMenuItem1.Size = new System.Drawing.Size(192, 6);
-            // 
-            // openProjectToolStripMenuItem
-            // 
-            this.openProjectToolStripMenuItem.Name = "openProjectToolStripMenuItem";
-            this.openProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
-            this.openProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
-            this.openProjectToolStripMenuItem.Text = "Open Project...";
-            this.openProjectToolStripMenuItem.Click += new System.EventHandler(this.openProjectToolStripMenuItem_Click);
-            // 
-            // closeProjectToolStripMenuItem
-            // 
-            this.closeProjectToolStripMenuItem.Name = "closeProjectToolStripMenuItem";
-            this.closeProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
-            this.closeProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
-            this.closeProjectToolStripMenuItem.Text = "Close Project";
-            this.closeProjectToolStripMenuItem.Click += new System.EventHandler(this.closeProjectToolStripMenuItem_Click);
-            // 
-            // saveProjectToolStripMenuItem
-            // 
-            this.saveProjectToolStripMenuItem.Name = "saveProjectToolStripMenuItem";
-            this.saveProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
-            this.saveProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
-            this.saveProjectToolStripMenuItem.Text = "Save Project...";
-            this.saveProjectToolStripMenuItem.Click += new System.EventHandler(this.saveProjectToolStripMenuItem_Click);
-            // 
-            // toolStripMenuItem2
-            // 
-            this.toolStripMenuItem2.Name = "toolStripMenuItem2";
-            this.toolStripMenuItem2.Size = new System.Drawing.Size(192, 6);
-            // 
-            // quitToolStripMenuItem
-            // 
-            this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
-            this.quitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q)));
-            this.quitToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
-            this.quitToolStripMenuItem.Text = "Quit";
-            // 
-            // scanToolStripMenuItem
-            // 
-            this.scanToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.scanToolStripMenuItem1,
-            this.cleanRescanToolStripMenuItem});
-            this.scanToolStripMenuItem.Name = "scanToolStripMenuItem";
-            this.scanToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
-            this.scanToolStripMenuItem.Text = "Scan";
-            // 
-            // scanToolStripMenuItem1
-            // 
-            this.scanToolStripMenuItem1.Name = "scanToolStripMenuItem1";
-            this.scanToolStripMenuItem1.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
-            this.scanToolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
-            this.scanToolStripMenuItem1.Text = "Scan";
-            this.scanToolStripMenuItem1.Click += new System.EventHandler(this.scanToolStripMenuItem1_Click);
-            // 
-            // label1
-            // 
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(3, 20);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(62, 13);
-            this.label1.TabIndex = 1;
-            this.label1.Text = "Project dirs:";
-            // 
-            // label2
-            // 
-            this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(3, 0);
-            this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(56, 13);
-            this.label2.TabIndex = 2;
-            this.label2.Text = "Last scan:";
-            // 
-            // tableLayoutPanel1
-            // 
-            this.tableLayoutPanel1.ColumnCount = 2;
-            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
-            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
-            this.tableLayoutPanel1.Controls.Add(this.includeDirsTextBox, 1, 2);
-            this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0);
-            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1);
-            this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2);
-            this.tableLayoutPanel1.Controls.Add(this.lastScanLabel, 1, 0);
-            this.tableLayoutPanel1.Controls.Add(this.projectDirsTextBox, 1, 1);
-            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24);
-            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
-            this.tableLayoutPanel1.RowCount = 3;
-            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
-            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
-            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
-            this.tableLayoutPanel1.Size = new System.Drawing.Size(605, 409);
-            this.tableLayoutPanel1.TabIndex = 3;
-            // 
-            // includeDirsTextBox
-            // 
-            this.includeDirsTextBox.ContextMenuStrip = this.includeDirsContextMenuStrip;
-            this.includeDirsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.includeDirsTextBox.Location = new System.Drawing.Point(103, 217);
-            this.includeDirsTextBox.Multiline = true;
-            this.includeDirsTextBox.Name = "includeDirsTextBox";
-            this.includeDirsTextBox.Size = new System.Drawing.Size(499, 189);
-            this.includeDirsTextBox.TabIndex = 6;
-            // 
-            // includeDirsContextMenuStrip
-            // 
-            this.includeDirsContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.toolStripMenuItem3});
-            this.includeDirsContextMenuStrip.Name = "projectDirContextMenuStrip";
-            this.includeDirsContextMenuStrip.Size = new System.Drawing.Size(157, 26);
-            // 
-            // toolStripMenuItem3
-            // 
-            this.toolStripMenuItem3.Name = "toolStripMenuItem3";
-            this.toolStripMenuItem3.Size = new System.Drawing.Size(156, 22);
-            this.toolStripMenuItem3.Text = "Add Directory...";
-            this.toolStripMenuItem3.Click += new System.EventHandler(this.include_AddDirectory_Click);
-            // 
-            // label3
-            // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(3, 214);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(64, 13);
-            this.label3.TabIndex = 3;
-            this.label3.Text = "Include dirs:";
-            // 
-            // lastScanLabel
-            // 
-            this.lastScanLabel.AutoSize = true;
-            this.lastScanLabel.Location = new System.Drawing.Point(103, 0);
-            this.lastScanLabel.Name = "lastScanLabel";
-            this.lastScanLabel.Size = new System.Drawing.Size(84, 13);
-            this.lastScanLabel.TabIndex = 4;
-            this.lastScanLabel.Text = "(never scanned)";
-            // 
-            // projectDirsTextBox
-            // 
-            this.projectDirsTextBox.ContextMenuStrip = this.projectDirContextMenuStrip;
-            this.projectDirsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.projectDirsTextBox.Location = new System.Drawing.Point(103, 23);
-            this.projectDirsTextBox.Multiline = true;
-            this.projectDirsTextBox.Name = "projectDirsTextBox";
-            this.projectDirsTextBox.Size = new System.Drawing.Size(499, 188);
-            this.projectDirsTextBox.TabIndex = 5;
-            // 
-            // projectDirContextMenuStrip
-            // 
-            this.projectDirContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.addDirectoryToolStripMenuItem});
-            this.projectDirContextMenuStrip.Name = "projectDirContextMenuStrip";
-            this.projectDirContextMenuStrip.Size = new System.Drawing.Size(157, 26);
-            // 
-            // addDirectoryToolStripMenuItem
-            // 
-            this.addDirectoryToolStripMenuItem.Name = "addDirectoryToolStripMenuItem";
-            this.addDirectoryToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
-            this.addDirectoryToolStripMenuItem.Text = "Add Directory...";
-            this.addDirectoryToolStripMenuItem.Click += new System.EventHandler(this.scan_AddDirectory_Click);
-            // 
-            // cleanRescanToolStripMenuItem
-            // 
-            this.cleanRescanToolStripMenuItem.Name = "cleanRescanToolStripMenuItem";
-            this.cleanRescanToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
-            this.cleanRescanToolStripMenuItem.Text = "Clean Rescan";
-            this.cleanRescanToolStripMenuItem.Click += new System.EventHandler(this.cleanRescanToolStripMenuItem_Click);
-            // 
-            // MainForm
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(605, 433);
-            this.Controls.Add(this.tableLayoutPanel1);
-            this.Controls.Add(this.menuBarMenuStrip);
-            this.MainMenuStrip = this.menuBarMenuStrip;
-            this.Name = "MainForm";
-            this.Text = "Header Hero";
-            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
-            this.menuBarMenuStrip.ResumeLayout(false);
-            this.menuBarMenuStrip.PerformLayout();
-            this.tableLayoutPanel1.ResumeLayout(false);
-            this.tableLayoutPanel1.PerformLayout();
-            this.includeDirsContextMenuStrip.ResumeLayout(false);
-            this.projectDirContextMenuStrip.ResumeLayout(false);
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.MenuStrip menuBarMenuStrip;
-        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem newProjectToolStripMenuItem;
-        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
-        private System.Windows.Forms.ToolStripMenuItem openProjectToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem closeProjectToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem saveProjectToolStripMenuItem;
-        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
-        private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem scanToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem scanToolStripMenuItem1;
-        private System.Windows.Forms.Label label1;
-        private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
-        private System.Windows.Forms.Label label3;
-        private System.Windows.Forms.Label lastScanLabel;
-        private System.Windows.Forms.ContextMenuStrip projectDirContextMenuStrip;
-        private System.Windows.Forms.ToolStripMenuItem addDirectoryToolStripMenuItem;
-        private System.Windows.Forms.ContextMenuStrip includeDirsContextMenuStrip;
-        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
-        private System.Windows.Forms.TextBox includeDirsTextBox;
-        private System.Windows.Forms.TextBox projectDirsTextBox;
-        private System.Windows.Forms.ToolStripMenuItem cleanRescanToolStripMenuItem;
-    }
-}
-

header_hero/MainForm.cs

-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-using System.IO;
-using HeaderHero.Serialization;
-
-namespace HeaderHero
-{
-    public partial class MainForm : Form
-    {
-        string _file;
-        string _last_save;
-        Data.Project _project;
-
-        public MainForm()
-        {
-            InitializeComponent();
-
-            _project = new Data.Project();
-            DisplayProject();
-            MarkSave();
-            
-            projectDirsTextBox.MouseDoubleClick += (_1, _2) => scan_AddDirectory_Click(_1, null);
-            includeDirsTextBox.MouseDoubleClick += (_1, _2) => include_AddDirectory_Click(_1, null);
-
-            string last = Properties.Settings.Default.LastProject;
-            if (last != null && last != "" && File.Exists(last))
-            {
-                Open(last);
-                scanToolStripMenuItem1_Click(null, null);
-            }
-        }
-
-        private void DisplayProject()
-        {
-            lastScanLabel.Text = _project.LastScan.ToString();
-            projectDirsTextBox.Text = String.Join("\r\n", _project.ScanDirectories.ToArray());
-            includeDirsTextBox.Text = String.Join("\r\n", _project.IncludeDirectories.ToArray());
-        }
-
-        private void ParseProject()
-        {
-            _project.ScanDirectories = projectDirsTextBox.Text.Trim().Split('\n', '\r').Where(s => s.Trim().Length > 0).ToList();
-            _project.IncludeDirectories = includeDirsTextBox.Text.Trim().Split('\n', '\r').Where(s => s.Trim().Length > 0).ToList();
-        }
-
-        #region Project Dirs
-
-        private void scan_AddDirectory_Click(object sender, EventArgs e)
-        {
-            ParseProject();
-            FolderBrowserDialog fbd = new FolderBrowserDialog();
-            if (fbd.ShowDialog() == DialogResult.OK) {
-                _project.ScanDirectories.Add( fbd.SelectedPath );
-                DisplayProject();
-            }
-        }
-
-        #endregion
-
-        #region Include Dirs
-
-        private void include_AddDirectory_Click(object sender, EventArgs e)
-        {
-            ParseProject();
-            FolderBrowserDialog fbd = new FolderBrowserDialog();
-            if (fbd.ShowDialog() == DialogResult.OK)
-            {
-                _project.IncludeDirectories.Add(fbd.SelectedPath);
-                DisplayProject();
-            }
-        }
-
-        #endregion
-
-        #region File Menu
-
-        private string _filter = "Header Hero (*.header_hero)|*.header_hero";
-
-        private void saveProjectToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            if (_file == null)
-            {
-                SaveFileDialog sfd = new SaveFileDialog();
-                sfd.Filter = _filter;
-                if (sfd.ShowDialog() == DialogResult.OK)
-                    _file = sfd.FileName;
-            }
-
-            if (_file == null)
-                return;
-
-            Properties.Settings.Default.LastProject = _file;
-            ParseProject();
-            Sjson.Save(JsonSerializer.Save(_project), _file);
-            MarkSave();
-        }
-
-        private void MarkSave()
-        {
-            if (_file != null)
-                Text = "Header Hero - " + _file;
-            else
-                Text = "Header Hero";
-            _last_save = Sjson.Encode( JsonSerializer.Save(_project) );
-        }
-
-        private bool CheckSave()
-        {
-            ParseProject();
-            if (_last_save == Sjson.Encode(JsonSerializer.Save(_project)))
-                return true;
-            saveProjectToolStripMenuItem_Click(null, null);
-            return true;
-        }
-
-        private void newProjectToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            if (CheckSave())
-            {
-                _file = null;
-                _project = new Data.Project();
-                DisplayProject();
-                MarkSave();
-            }
-        }
-
-        private void closeProjectToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            newProjectToolStripMenuItem_Click(sender, e);
-        }
-
-        private void Open(string path)
-        {
-            _file = path;
-            Properties.Settings.Default.LastProject = _file;
-            _project = new Data.Project();
-            JsonSerializer.Load(_project, Sjson.Load(_file));
-            MarkSave();
-            DisplayProject();
-        }
-
-        private void openProjectToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            if (CheckSave())
-            {
-                OpenFileDialog ofd = new OpenFileDialog();
-                ofd.Filter = _filter;
-                if (ofd.ShowDialog() == DialogResult.OK)
-                    Open(ofd.FileName);
-            }
-
-        }
-
-        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
-        {
-            Properties.Settings.Default.Save();
-            if (!CheckSave())
-                e.Cancel = true;
-        }
-
-        #endregion
-
-        #region Scan Menu
-
-        private void scanToolStripMenuItem1_Click(object sender, EventArgs e)
-        {
-            ParseProject();
-            Parser.Scanner scanner = new Parser.Scanner(_project);
-            
-            DateTime started = DateTime.Now;
-            ProgressDialog d = new ProgressDialog();
-            d.Text = "Scanning source files...";
-            d.Work = (feedback) => scanner.Rescan(feedback);
-            d.Start();
-            _project.LastScan = started;
-
-            DisplayProject();
-
-            ReportForm rf = new ReportForm(_project, scanner);
-            rf.Show();
-        }
-
-        private void cleanRescanToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            _project.Clean();
-            scanToolStripMenuItem1_Click(sender, e);
-        }
-
-        #endregion
-    }
-}

header_hero/MainForm.resx

-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <metadata name="menuBarMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 17</value>
-  </metadata>
-  <metadata name="includeDirsContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>379, 17</value>
-  </metadata>
-  <metadata name="projectDirContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>174, 17</value>
-  </metadata>
-</root>

header_hero/Parser/Parser.cs

             }
         };
 
+        enum States { Start, Hash, Include, AngleBracket, Quote }
+        enum ParseResult { Ok, Error }
+
+        static ParseResult ParseLine(string line, Result result)
+        {
+            int i = 0;
+            int path_start = 0;
+            States state = States.Start;
+
+            while (true) {
+                if (i >= line.Length)
+                    return ParseResult.Error;
+
+                char c = line[i];
+                ++i;
+               
+                if (c == ' ' || c == '\t') {
+                
+                } else if (state == States.Start) {
+                    if (c == '#')
+                        state = States.Hash;
+                    else if (c == '/') {
+                        if (i >= line.Length)
+                            return ParseResult.Error;
+                        if (line[i] == '/')
+                            return ParseResult.Ok; // Matched C++ style comment
+                    } else
+                        return ParseResult.Error;
+                } else if (state == States.Hash) {
+                    --i;
+                    if (line.IndexOf("include", i) == i) {
+                        i += 7;
+                        state = States.Include;
+                    } else
+                        return ParseResult.Ok; // Matched preprocessor other than #include
+                } else if (state == States.Include) {
+                    if (c == '<') {
+                        path_start = i;
+                        state = States.AngleBracket;
+                    } else if (c == '"') {
+                        path_start = i;
+                         state = States.Quote;
+                    } else
+                        return ParseResult.Error;
+                } else if (state == States.AngleBracket) {
+                    if (c == '>') {
+                        result.SystemIncludes.Add(line.Substring(path_start, i-path_start-1));
+                        return ParseResult.Ok;
+                    }
+                } else if (state == States.Quote) {
+                    if (c == '"') {
+                        result.LocalIncludes.Add(line.Substring(path_start, i-path_start-1));
+                        return ParseResult.Ok;
+                    }
+                }
+            }
+        }
+
         /// <summary>
         /// Simple parser... only looks for #include lines. Does not take #defines or comments into account.
         /// </summary>
             res.Lines = lines.Count();
             foreach (string line in lines)
             {
-                if (line.Contains("#include"))
+                if (line.Contains('#') && line.Contains("include"))
                 {
-                    int i = line.IndexOf('#');
-                    int lt = line.IndexOf('<', i);
-                    int gt = line.IndexOf('>', lt + 1);
-                    int qt = line.IndexOf('"', i);
-                    int qt2 = line.IndexOf('"', qt + 1);
-                    
-                    if (lt>=0 && gt>=0 && qt<0)
-                        res.SystemIncludes.Add(line.Substring(lt+1,gt-lt-1));
-                    else if (qt>=0 && qt2>=0 && lt<0)
-                        res.LocalIncludes.Add(line.Substring(qt+1,qt2-qt-1));
+                    ParseResult r = ParseLine(line, res);
+                    if (r == ParseResult.Error)
+                        errors.Add("Could not parse line: " + line + " in file: " + fi.FullName);
+                }
                     else
                         errors.Add("Could not parse line: " + line + " in file: " + fi.FullName);
-                }
             }
             return res;
         }

header_hero/Program.cs

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows.Forms;
-
-namespace HeaderHero
-{
-    static class Program
-    {
-        /// <summary>
-        /// The main entry point for the application.
-        /// </summary>
-        [STAThread]
-        static void Main()
-        {
-            Application.EnableVisualStyles();
-            Application.SetCompatibleTextRenderingDefault(false);
-            Application.Run(new MainForm());
-        }
-    }
-}

header_hero/ProgressDialog.Designer.cs

-namespace HeaderHero
-{
-    partial class ProgressDialog
-    {
-        /// <summary>
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary>
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Windows Form Designer generated code
-
-        /// <summary>
-        /// Required method for Designer support - do not modify
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.progressBar = new System.Windows.Forms.ProgressBar();
-            this.messageLabel = new System.Windows.Forms.Label();
-            this.progressReportLabel = new System.Windows.Forms.Label();
-            this.SuspendLayout();
-            // 
-            // progressBar
-            // 
-            this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                        | System.Windows.Forms.AnchorStyles.Right)));
-            this.progressBar.Location = new System.Drawing.Point(78, 40);
-            this.progressBar.Name = "progressBar";
-            this.progressBar.Size = new System.Drawing.Size(647, 23);
-            this.progressBar.TabIndex = 0;
-            // 
-            // messageLabel
-            // 
-            this.messageLabel.AutoSize = true;
-            this.messageLabel.Location = new System.Drawing.Point(12, 18);
-            this.messageLabel.Name = "messageLabel";
-            this.messageLabel.Size = new System.Drawing.Size(50, 13);
-            this.messageLabel.TabIndex = 3;
-            this.messageLabel.Text = "Message";
-            // 
-            // progressReportLabel
-            // 
-            this.progressReportLabel.AutoSize = true;
-            this.progressReportLabel.Location = new System.Drawing.Point(12, 46);
-            this.progressReportLabel.Name = "progressReportLabel";
-            this.progressReportLabel.Size = new System.Drawing.Size(60, 13);
-            this.progressReportLabel.TabIndex = 4;
-            this.progressReportLabel.Text = "9999/9999";
-            // 
-            // ProgressDialog
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(737, 79);
-            this.ControlBox = false;
-            this.Controls.Add(this.progressReportLabel);
-            this.Controls.Add(this.messageLabel);
-            this.Controls.Add(this.progressBar);
-            this.MaximizeBox = false;
-            this.MinimizeBox = false;
-            this.Name = "ProgressDialog";
-            this.Text = "Progress...";
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.ProgressBar progressBar;
-        private System.Windows.Forms.Label messageLabel;
-        private System.Windows.Forms.Label progressReportLabel;
-    }
-}

header_hero/ProgressDialog.cs

-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-
-namespace HeaderHero
-{
-    public partial class ProgressDialog : Form
-    {
-        BackgroundWorker _worker;
-
-        public delegate void ProgressDialogWork(ProgressFeedback feedback);
-        public ProgressDialogWork Work;
-
-        ProgressFeedback _feedback = new ProgressFeedback();
-
-        public ProgressDialog()
-        {
-            InitializeComponent();
-
-            Poll(null, null);
-
-            _worker = new BackgroundWorker();
-            _worker.DoWork += DoWork;
-            _worker.RunWorkerCompleted += RunWorkerCompleted;
-        }
-
-        public void Start()
-        {
-            _feedback.Title = Text;
-            messageLabel.Text = "";
-
-            Timer poll_timer = new Timer();
-            poll_timer.Tick += Poll;
-            poll_timer.Interval = 100;
-            poll_timer.Start();
-
-            _worker.RunWorkerAsync();
-
-            ShowDialog();
-
-            poll_timer.Stop();
-        }
-
-        private void DoWork(object sender, DoWorkEventArgs e)
-        {
-            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
-            Work(_feedback);
-        }
-
-        private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
-        {
-            if (e.Error != null)
-                MessageBox.Show("Error: " + e.Error.ToString());
-            this.Close();
-        }
-
-        private void Poll(object sender, EventArgs e)
-        {
-            progressBar.Maximum = _feedback.Count;
-            progressBar.Value = _feedback.Item;
-            progressReportLabel.Text = String.Format("{0}/{1}", _feedback.Item, _feedback.Count);
-            Text = _feedback.Title;
-            messageLabel.Text = _feedback.Message;
-        }
-    }
-
-    public class ProgressFeedback
-    {
-        public string Title = "";
-        public int Item = 0;
-        public int Count = 0;
-        public string Message = "";
-    }
-}

header_hero/ReportForm.Designer.cs

-namespace HeaderHero
-{
-    partial class ReportForm
-    {
-        /// <summary>
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary>
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-        #region Windows Form Designer generated code
-
-        /// <summary>
-        /// Required method for Designer support - do not modify
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.tabPages = new System.Windows.Forms.TabControl();
-            this.reportTab = new System.Windows.Forms.TabPage();
-            this.reportBrowser = new System.Windows.Forms.WebBrowser();
-            this.includeTab = new System.Windows.Forms.TabPage();
-            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
-            this.includesListView = new System.Windows.Forms.ListView();
-            this.fileListView = new System.Windows.Forms.ListView();
-            this.label3 = new System.Windows.Forms.Label();
-            this.label2 = new System.Windows.Forms.Label();
-            this.label1 = new System.Windows.Forms.Label();
-            this.includedByListView = new System.Windows.Forms.ListView();
-            this.errorsTab = new System.Windows.Forms.TabPage();
-            this.errorsListView = new System.Windows.Forms.ListView();
-            this.missingTab = new System.Windows.Forms.TabPage();
-            this.missingFilesListView = new System.Windows.Forms.ListView();
-            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
-            this.scanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.rescanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-            this.tabPages.SuspendLayout();
-            this.reportTab.SuspendLayout();
-            this.includeTab.SuspendLayout();
-            this.tableLayoutPanel1.SuspendLayout();
-            this.errorsTab.SuspendLayout();
-            this.missingTab.SuspendLayout();
-            this.menuStrip1.SuspendLayout();
-            this.SuspendLayout();
-            // 
-            // tabPages
-            // 
-            this.tabPages.Controls.Add(this.reportTab);
-            this.tabPages.Controls.Add(this.includeTab);
-            this.tabPages.Controls.Add(this.errorsTab);
-            this.tabPages.Controls.Add(this.missingTab);
-            this.tabPages.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.tabPages.Location = new System.Drawing.Point(0, 24);
-            this.tabPages.Name = "tabPages";
-            this.tabPages.SelectedIndex = 0;
-            this.tabPages.Size = new System.Drawing.Size(641, 663);
-            this.tabPages.TabIndex = 0;
-            // 
-            // reportTab
-            // 
-            this.reportTab.Controls.Add(this.reportBrowser);
-            this.reportTab.Location = new System.Drawing.Point(4, 22);
-            this.reportTab.Name = "reportTab";
-            this.reportTab.Padding = new System.Windows.Forms.Padding(3);
-            this.reportTab.Size = new System.Drawing.Size(633, 637);
-            this.reportTab.TabIndex = 0;
-            this.reportTab.Text = "Report";
-            this.reportTab.UseVisualStyleBackColor = true;
-            // 
-            // reportBrowser
-            // 
-            this.reportBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.reportBrowser.Location = new System.Drawing.Point(3, 3);
-            this.reportBrowser.MinimumSize = new System.Drawing.Size(20, 20);
-            this.reportBrowser.Name = "reportBrowser";
-            this.reportBrowser.Size = new System.Drawing.Size(627, 631);
-            this.reportBrowser.TabIndex = 0;
-            // 
-            // includeTab
-            // 
-            this.includeTab.Controls.Add(this.tableLayoutPanel1);
-            this.includeTab.Location = new System.Drawing.Point(4, 22);
-            this.includeTab.Name = "includeTab";
-            this.includeTab.Padding = new System.Windows.Forms.Padding(3);
-            this.includeTab.Size = new System.Drawing.Size(633, 661);
-            this.includeTab.TabIndex = 3;
-            this.includeTab.Text = "Includes";
-            this.includeTab.UseVisualStyleBackColor = true;
-            // 
-            // tableLayoutPanel1
-            // 
-            this.tableLayoutPanel1.ColumnCount = 3;
-            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
-            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
-            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
-            this.tableLayoutPanel1.Controls.Add(this.includesListView, 2, 1);
-            this.tableLayoutPanel1.Controls.Add(this.fileListView, 1, 1);
-            this.tableLayoutPanel1.Controls.Add(this.label3, 2, 0);
-            this.tableLayoutPanel1.Controls.Add(this.label2, 1, 0);
-            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
-            this.tableLayoutPanel1.Controls.Add(this.includedByListView, 0, 1);
-            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
-            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
-            this.tableLayoutPanel1.RowCount = 2;
-            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
-            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
-            this.tableLayoutPanel1.Size = new System.Drawing.Size(627, 655);
-            this.tableLayoutPanel1.TabIndex = 0;
-            // 
-            // includesListView
-            // 
-            this.includesListView.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.includesListView.Location = new System.Drawing.Point(421, 23);
-            this.includesListView.Name = "includesListView";
-            this.includesListView.Size = new System.Drawing.Size(203, 629);
-            this.includesListView.TabIndex = 5;
-            this.includesListView.UseCompatibleStateImageBehavior = false;
-            this.includesListView.View = System.Windows.Forms.View.List;
-            // 
-            // fileListView
-            // 
-            this.fileListView.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.fileListView.Location = new System.Drawing.Point(212, 23);
-            this.fileListView.Name = "fileListView";
-            this.fileListView.Size = new System.Drawing.Size(203, 629);
-            this.fileListView.TabIndex = 4;
-            this.fileListView.UseCompatibleStateImageBehavior = false;
-            this.fileListView.View = System.Windows.Forms.View.List;
-            // 
-            // label3
-            // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(421, 0);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(50, 13);
-            this.label3.TabIndex = 2;
-            this.label3.Text = "Includes:";
-            // 
-            // label2
-            // 
-            this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(212, 0);
-            this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(26, 13);
-            this.label2.TabIndex = 1;
-            this.label2.Text = "File:";
-            // 
-            // label1
-            // 
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(3, 0);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(65, 13);
-            this.label1.TabIndex = 0;
-            this.label1.Text = "Included by:";
-            // 
-            // includedByListView
-            // 
-            this.includedByListView.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.includedByListView.Location = new System.Drawing.Point(3, 23);
-            this.includedByListView.Name = "includedByListView";
-            this.includedByListView.Size = new System.Drawing.Size(203, 629);
-            this.includedByListView.TabIndex = 3;
-            this.includedByListView.UseCompatibleStateImageBehavior = false;
-            this.includedByListView.View = System.Windows.Forms.View.List;
-            // 
-            // errorsTab
-            // 
-            this.errorsTab.Controls.Add(this.errorsListView);
-            this.errorsTab.Location = new System.Drawing.Point(4, 22);
-            this.errorsTab.Name = "errorsTab";
-            this.errorsTab.Padding = new System.Windows.Forms.Padding(3);
-            this.errorsTab.Size = new System.Drawing.Size(633, 661);
-            this.errorsTab.TabIndex = 1;
-            this.errorsTab.Text = "Errors";
-            this.errorsTab.UseVisualStyleBackColor = true;
-            // 
-            // errorsListView
-            // 
-            this.errorsListView.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.errorsListView.Location = new System.Drawing.Point(3, 3);
-            this.errorsListView.Name = "errorsListView";
-            this.errorsListView.Size = new System.Drawing.Size(627, 655);
-            this.errorsListView.TabIndex = 0;
-            this.errorsListView.UseCompatibleStateImageBehavior = false;
-            this.errorsListView.View = System.Windows.Forms.View.List;
-            // 
-            // missingTab
-            // 
-            this.missingTab.Controls.Add(this.missingFilesListView);
-            this.missingTab.Location = new System.Drawing.Point(4, 22);
-            this.missingTab.Name = "missingTab";
-            this.missingTab.Padding = new System.Windows.Forms.Padding(3);
-            this.missingTab.Size = new System.Drawing.Size(633, 661);
-            this.missingTab.TabIndex = 2;
-            this.missingTab.Text = "Missing Files";
-            this.missingTab.UseVisualStyleBackColor = true;
-            // 
-            // missingFilesListView
-            // 
-            this.missingFilesListView.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.missingFilesListView.Location = new System.Drawing.Point(3, 3);
-            this.missingFilesListView.Name = "missingFilesListView";
-            this.missingFilesListView.Size = new System.Drawing.Size(627, 655);
-            this.missingFilesListView.TabIndex = 1;
-            this.missingFilesListView.UseCompatibleStateImageBehavior = false;
-            this.missingFilesListView.View = System.Windows.Forms.View.List;
-            // 
-            // menuStrip1
-            // 
-            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.scanToolStripMenuItem});
-            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
-            this.menuStrip1.Name = "menuStrip1";
-            this.menuStrip1.Size = new System.Drawing.Size(641, 24);
-            this.menuStrip1.TabIndex = 1;
-            this.menuStrip1.Text = "menuStrip1";
-            // 
-            // scanToolStripMenuItem
-            // 
-            this.scanToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.rescanToolStripMenuItem});
-            this.scanToolStripMenuItem.Name = "scanToolStripMenuItem";
-            this.scanToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
-            this.scanToolStripMenuItem.Text = "Scan";
-            // 
-            // rescanToolStripMenuItem
-            // 
-            this.rescanToolStripMenuItem.Name = "rescanToolStripMenuItem";
-            this.rescanToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
-            this.rescanToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
-            this.rescanToolStripMenuItem.Text = "Rescan";
-            this.rescanToolStripMenuItem.Click += new System.EventHandler(this.rescanToolStripMenuItem_Click);
-            // 
-            // ReportForm
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(641, 687);
-            this.Controls.Add(this.tabPages);
-            this.Controls.Add(this.menuStrip1);
-            this.MainMenuStrip = this.menuStrip1;
-            this.Name = "ReportForm";
-            this.Text = "Report";
-            this.tabPages.ResumeLayout(false);
-            this.reportTab.ResumeLayout(false);
-            this.includeTab.ResumeLayout(false);
-            this.tableLayoutPanel1.ResumeLayout(false);
-            this.tableLayoutPanel1.PerformLayout();
-            this.errorsTab.ResumeLayout(false);
-            this.missingTab.ResumeLayout(false);
-            this.menuStrip1.ResumeLayout(false);
-            this.menuStrip1.PerformLayout();
-            this.ResumeLayout(false);
-            this.PerformLayout();
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.TabControl tabPages;
-        private System.Windows.Forms.TabPage reportTab;
-        private System.Windows.Forms.TabPage errorsTab;
-        private System.Windows.Forms.TabPage missingTab;
-        private System.Windows.Forms.ListView errorsListView;
-        private System.Windows.Forms.ListView missingFilesListView;
-        private System.Windows.Forms.TabPage includeTab;
-        private System.Windows.Forms.WebBrowser reportBrowser;
-        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
-        private System.Windows.Forms.ListView includesListView;
-        private System.Windows.Forms.ListView fileListView;
-        private System.Windows.Forms.Label label3;
-        private System.Windows.Forms.Label label2;
-        private System.Windows.Forms.Label label1;
-        private System.Windows.Forms.ListView includedByListView;
-        private System.Windows.Forms.MenuStrip menuStrip1;
-        private System.Windows.Forms.ToolStripMenuItem scanToolStripMenuItem;
-        private System.Windows.Forms.ToolStripMenuItem rescanToolStripMenuItem;
-    }
-}

header_hero/ReportForm.cs

-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-using System.IO;
-
-namespace HeaderHero
-{
-    public partial class ReportForm : Form
-    {
-        Data.Project _project;
-        Parser.Scanner _scanner;
-        Parser.Analytics _analytics;
-        
-        public ReportForm(Data.Project project, Parser.Scanner scanner)
-        {
-            InitializeComponent();
-
-            includedByListView.MouseDoubleClick += new MouseEventHandler(includedByListView_MouseDoubleClick);
-            includesListView.MouseDoubleClick += new MouseEventHandler(includedByListView_MouseDoubleClick);
-
-            Setup(project, scanner);
-        }
-
-        private void Setup(Data.Project project, Parser.Scanner scanner)
-        {
-            _project = project;
-            _scanner = scanner;
-            _analytics = Parser.Analytics.Analyze(_project);
-            
-            errorsListView.Items.Clear();
-            foreach (string s in scanner.Errors)
-                errorsListView.Items.Add(s);
-            missingFilesListView.Items.Clear();
-            foreach (string s in scanner.NotFound.OrderBy(s => s))
-                missingFilesListView.Items.Add(s);
-
-            string file = Parser.Report.Generate(_project, _analytics);
-            if (reportBrowser.Url != null)
-                reportBrowser.Refresh();
-            else
-                reportBrowser.Navigate(file);
-            reportBrowser.Navigating += reportBrowser_Navigating;
-        }
-
-        void includedByListView_MouseDoubleClick(object sender, MouseEventArgs e)
-        {
-            ListView lv = sender as ListView;
-            if (lv.SelectedItems.Count == 1)
-            {
-                string file = lv.SelectedItems[0].Tag as string;
-                Inspect(file);
-            }
-        }
-
-        private string _inspecting;
-
-        private void Inspect(string file)
-        {
-            _inspecting = file;
-
-            {
-                fileListView.Items.Clear();
-                ListViewItem item = new ListViewItem(Path.GetFileName(file));
-                item.Tag = file;
-                fileListView.Items.Add(item);
-            }
-
-            {
-                includesListView.Items.Clear();
-                foreach (string s in _project.Files[file].AbsoluteIncludes.OrderByDescending(f => _analytics.Items[f].AllIncludes.Count))
-                {
-                    string text = string.Format("{0} ({1})", Path.GetFileName(s), _analytics.Items[s].AllIncludes.Count);
-                    ListViewItem item = new ListViewItem(text);
-                    item.Tag = s;
-                    includesListView.Items.Add(item);
-                }
-            }
-
-            {
-                includedByListView.Items.Clear();
-                IEnumerable<string> included = _project.Files.Where(kvp => kvp.Value.AbsoluteIncludes.Contains(file)).Select(kvp => kvp.Key);
-                foreach (string s in included.OrderByDescending(s => _analytics.Items[s].AllIncludedBy.Count))
-                {
-                    string text = string.Format("{0} ({1})", Path.GetFileName(s), _analytics.Items[s].AllIncludedBy.Count);
-                    ListViewItem item = new ListViewItem(text);
-                    item.Tag = s;
-                    includedByListView.Items.Add(item);
-                }
-            }
-        }
-
-        private void reportBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
-        {
-            if (e.Url.Host == "inspect")
-            {
-                string file = e.Url.Query.Substring(1);
-                e.Cancel = true;
-                Inspect(Uri.UnescapeDataString(file));
-                tabPages.SelectedTab = includeTab;
-            }
-        }
-
-        private void rescanToolStripMenuItem_Click(object sender, EventArgs e)
-        {
-            DateTime started = DateTime.Now;
-            ProgressDialog d = new ProgressDialog();
-            d.Text = "Scanning source files...";
-            d.Work = (feedback) => _scanner.Rescan(feedback);
-            d.Start();
-            _project.LastScan = started;
-
-            Setup(_project, _scanner);
-            if (_inspecting != null)
-                Inspect(_inspecting);
-        }
-    }
-}

header_hero/ReportForm.resx

-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>122, 17</value>
-  </metadata>
-</root>

header_hero/Windows/MainForm.Designer.cs

+namespace HeaderHero
+{
+    partial class MainForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            this.menuBarMenuStrip = new System.Windows.Forms.MenuStrip();
+            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.newProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
+            this.openProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.closeProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.saveProjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
+            this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.scanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.scanToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+            this.label1 = new System.Windows.Forms.Label();
+            this.label2 = new System.Windows.Forms.Label();
+            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+            this.includeDirsTextBox = new System.Windows.Forms.TextBox();
+            this.includeDirsContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+            this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
+            this.label3 = new System.Windows.Forms.Label();
+            this.lastScanLabel = new System.Windows.Forms.Label();
+            this.projectDirsTextBox = new System.Windows.Forms.TextBox();
+            this.projectDirContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+            this.addDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.cleanRescanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.menuBarMenuStrip.SuspendLayout();
+            this.tableLayoutPanel1.SuspendLayout();
+            this.includeDirsContextMenuStrip.SuspendLayout();
+            this.projectDirContextMenuStrip.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // menuBarMenuStrip
+            // 
+            this.menuBarMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.fileToolStripMenuItem,
+            this.scanToolStripMenuItem});
+            this.menuBarMenuStrip.Location = new System.Drawing.Point(0, 0);
+            this.menuBarMenuStrip.Name = "menuBarMenuStrip";
+            this.menuBarMenuStrip.Size = new System.Drawing.Size(605, 24);
+            this.menuBarMenuStrip.TabIndex = 0;
+            this.menuBarMenuStrip.Text = "menuStrip1";
+            // 
+            // fileToolStripMenuItem
+            // 
+            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.newProjectToolStripMenuItem,
+            this.toolStripMenuItem1,
+            this.openProjectToolStripMenuItem,
+            this.closeProjectToolStripMenuItem,
+            this.saveProjectToolStripMenuItem,
+            this.toolStripMenuItem2,
+            this.quitToolStripMenuItem});
+            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
+            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
+            this.fileToolStripMenuItem.Text = "File";
+            // 
+            // newProjectToolStripMenuItem
+            // 
+            this.newProjectToolStripMenuItem.Name = "newProjectToolStripMenuItem";
+            this.newProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
+            this.newProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
+            this.newProjectToolStripMenuItem.Text = "New Project";
+            this.newProjectToolStripMenuItem.Click += new System.EventHandler(this.newProjectToolStripMenuItem_Click);
+            // 
+            // toolStripMenuItem1
+            // 
+            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+            this.toolStripMenuItem1.Size = new System.Drawing.Size(192, 6);
+            // 
+            // openProjectToolStripMenuItem
+            // 
+            this.openProjectToolStripMenuItem.Name = "openProjectToolStripMenuItem";
+            this.openProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
+            this.openProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
+            this.openProjectToolStripMenuItem.Text = "Open Project...";
+            this.openProjectToolStripMenuItem.Click += new System.EventHandler(this.openProjectToolStripMenuItem_Click);
+            // 
+            // closeProjectToolStripMenuItem
+            // 
+            this.closeProjectToolStripMenuItem.Name = "closeProjectToolStripMenuItem";
+            this.closeProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
+            this.closeProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
+            this.closeProjectToolStripMenuItem.Text = "Close Project";
+            this.closeProjectToolStripMenuItem.Click += new System.EventHandler(this.closeProjectToolStripMenuItem_Click);
+            // 
+            // saveProjectToolStripMenuItem
+            // 
+            this.saveProjectToolStripMenuItem.Name = "saveProjectToolStripMenuItem";
+            this.saveProjectToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
+            this.saveProjectToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
+            this.saveProjectToolStripMenuItem.Text = "Save Project...";
+            this.saveProjectToolStripMenuItem.Click += new System.EventHandler(this.saveProjectToolStripMenuItem_Click);
+            // 
+            // toolStripMenuItem2
+            // 
+            this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+            this.toolStripMenuItem2.Size = new System.Drawing.Size(192, 6);
+            // 
+            // quitToolStripMenuItem
+            // 
+            this.quitToolStripMenuItem.Name = "quitToolStripMenuItem";
+            this.quitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q)));
+            this.quitToolStripMenuItem.Size = new System.Drawing.Size(195, 22);
+            this.quitToolStripMenuItem.Text = "Quit";
+            // 
+            // scanToolStripMenuItem
+            // 
+            this.scanToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.scanToolStripMenuItem1,
+            this.cleanRescanToolStripMenuItem});
+            this.scanToolStripMenuItem.Name = "scanToolStripMenuItem";
+            this.scanToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
+            this.scanToolStripMenuItem.Text = "Scan";
+            // 
+            // scanToolStripMenuItem1
+            // 
+            this.scanToolStripMenuItem1.Name = "scanToolStripMenuItem1";
+            this.scanToolStripMenuItem1.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.R)));
+            this.scanToolStripMenuItem1.Size = new System.Drawing.Size(152, 22);
+            this.scanToolStripMenuItem1.Text = "Scan";
+            this.scanToolStripMenuItem1.Click += new System.EventHandler(this.scanToolStripMenuItem1_Click);
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(3, 20);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(62, 13);
+            this.label1.TabIndex = 1;
+            this.label1.Text = "Project dirs:";
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(3, 0);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(56, 13);
+            this.label2.TabIndex = 2;
+            this.label2.Text = "Last scan:";
+            // 
+            // tableLayoutPanel1
+            // 
+            this.tableLayoutPanel1.ColumnCount = 2;
+            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
+            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+            this.tableLayoutPanel1.Controls.Add(this.includeDirsTextBox, 1, 2);
+            this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0);
+            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1);
+            this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2);
+            this.tableLayoutPanel1.Controls.Add(this.lastScanLabel, 1, 0);
+            this.tableLayoutPanel1.Controls.Add(this.projectDirsTextBox, 1, 1);
+            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24);
+            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+            this.tableLayoutPanel1.RowCount = 3;
+            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+            this.tableLayoutPanel1.Size = new System.Drawing.Size(605, 409);
+            this.tableLayoutPanel1.TabIndex = 3;
+            // 
+            // includeDirsTextBox
+            // 
+            this.includeDirsTextBox.ContextMenuStrip = this.includeDirsContextMenuStrip;
+            this.includeDirsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.includeDirsTextBox.Location = new System.Drawing.Point(103, 217);
+            this.includeDirsTextBox.Multiline = true;
+            this.includeDirsTextBox.Name = "includeDirsTextBox";
+            this.includeDirsTextBox.Size = new System.Drawing.Size(499, 189);
+            this.includeDirsTextBox.TabIndex = 6;
+            // 
+            // includeDirsContextMenuStrip
+            // 
+            this.includeDirsContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripMenuItem3});
+            this.includeDirsContextMenuStrip.Name = "projectDirContextMenuStrip";
+            this.includeDirsContextMenuStrip.Size = new System.Drawing.Size(157, 26);
+            // 
+            // toolStripMenuItem3
+            // 
+            this.toolStripMenuItem3.Name = "toolStripMenuItem3";
+            this.toolStripMenuItem3.Size = new System.Drawing.Size(156, 22);
+            this.toolStripMenuItem3.Text = "Add Directory...";
+            this.toolStripMenuItem3.Click += new System.EventHandler(this.include_AddDirectory_Click);
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(3, 214);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(64, 13);
+            this.label3.TabIndex = 3;
+            this.label3.Text = "Include dirs:";
+            // 
+            // lastScanLabel
+            // 
+            this.lastScanLabel.AutoSize = true;
+            this.lastScanLabel.Location = new System.Drawing.Point(103, 0);
+            this.lastScanLabel.Name = "lastScanLabel";
+            this.lastScanLabel.Size = new System.Drawing.Size(84, 13);
+            this.lastScanLabel.TabIndex = 4;
+            this.lastScanLabel.Text = "(never scanned)";
+            // 
+            // projectDirsTextBox
+            // 
+            this.projectDirsTextBox.ContextMenuStrip = this.projectDirContextMenuStrip;
+            this.projectDirsTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.projectDirsTextBox.Location = new System.Drawing.Point(103, 23);
+            this.projectDirsTextBox.Multiline = true;
+            this.projectDirsTextBox.Name = "projectDirsTextBox";
+            this.projectDirsTextBox.Size = new System.Drawing.Size(499, 188);
+            this.projectDirsTextBox.TabIndex = 5;
+            // 
+            // projectDirContextMenuStrip
+            // 
+            this.projectDirContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.addDirectoryToolStripMenuItem});
+            this.projectDirContextMenuStrip.Name = "projectDirContextMenuStrip";
+            this.projectDirContextMenuStrip.Size = new System.Drawing.Size(157, 26);
+            // 
+            // addDirectoryToolStripMenuItem
+            // 
+            this.addDirectoryToolStripMenuItem.Name = "addDirectoryToolStripMenuItem";
+            this.addDirectoryToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
+            this.addDirectoryToolStripMenuItem.Text = "Add Directory...";
+            this.addDirectoryToolStripMenuItem.Click += new System.EventHandler(this.scan_AddDirectory_Click);
+            // 
+            // cleanRescanToolStripMenuItem
+            // 
+            this.cleanRescanToolStripMenuItem.Name = "cleanRescanToolStripMenuItem";
+            this.cleanRescanToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.cleanRescanToolStripMenuItem.Text = "Clean Rescan";
+            this.cleanRescanToolStripMenuItem.Click += new System.EventHandler(this.cleanRescanToolStripMenuItem_Click);
+            // 
+            // MainForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(605, 433);
+            this.Controls.Add(this.tableLayoutPanel1);
+            this.Controls.Add(this.menuBarMenuStrip);
+            this.MainMenuStrip = this.menuBarMenuStrip;
+            this.Name = "MainForm";
+            this.Text = "Header Hero";
+            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
+            this.menuBarMenuStrip.ResumeLayout(false);
+            this.menuBarMenuStrip.PerformLayout();
+            this.tableLayoutPanel1.ResumeLayout(false);
+            this.tableLayoutPanel1.PerformLayout();
+            this.includeDirsContextMenuStrip.ResumeLayout(false);
+            this.projectDirContextMenuStrip.ResumeLayout(false);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.MenuStrip menuBarMenuStrip;
+        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem newProjectToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
+        private System.Windows.Forms.ToolStripMenuItem openProjectToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem closeProjectToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem saveProjectToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
+        private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem scanToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem scanToolStripMenuItem1;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.Label lastScanLabel;
+        private System.Windows.Forms.ContextMenuStrip projectDirContextMenuStrip;
+        private System.Windows.Forms.ToolStripMenuItem addDirectoryToolStripMenuItem;
+        private System.Windows.Forms.ContextMenuStrip includeDirsContextMenuStrip;
+        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3;
+        private System.Windows.Forms.TextBox includeDirsTextBox;
+        private System.Windows.Forms.TextBox projectDirsTextBox;
+        private System.Windows.Forms.ToolStripMenuItem cleanRescanToolStripMenuItem;
+    }
+}
+

header_hero/Windows/MainForm.cs

+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+using HeaderHero.Serialization;
+
+namespace HeaderHero
+{
+    public partial class MainForm : Form
+    {
+        string _file;
+        string _last_save;
+        Data.Project _project;
+
+        public MainForm()
+        {
+            InitializeComponent();
+
+            _project = new Data.Project();
+            DisplayProject();
+            MarkSave();
+            
+            projectDirsTextBox.MouseDoubleClick += (_1, _2) => scan_AddDirectory_Click(_1, null);
+            includeDirsTextBox.MouseDoubleClick += (_1, _2) => include_AddDirectory_Click(_1, null);
+
+            string last = Properties.Settings.Default.LastProject;
+            if (last != null && last != "" && File.Exists(last))
+            {
+                Open(last);
+                scanToolStripMenuItem1_Click(null, null);
+            }
+        }
+
+        private void DisplayProject()
+        {
+            lastScanLabel.Text = _project.LastScan.ToString();
+            projectDirsTextBox.Text = String.Join("\r\n", _project.ScanDirectories.ToArray());
+            includeDirsTextBox.Text = String.Join("\r\n", _project.IncludeDirectories.ToArray());
+        }
+
+        private void ParseProject()
+        {
+            _project.ScanDirectories = projectDirsTextBox.Text.Trim().Split('\n', '\r').Where(s => s.Trim().Length > 0).ToList();
+            _project.IncludeDirectories = includeDirsTextBox.Text.Trim().Split('\n', '\r').Where(s => s.Trim().Length > 0).ToList();
+        }
+
+        #region Project Dirs
+
+        private void scan_AddDirectory_Click(object sender, EventArgs e)
+        {
+            ParseProject();
+            FolderBrowserDialog fbd = new FolderBrowserDialog();
+            if (fbd.ShowDialog() == DialogResult.OK) {
+                _project.ScanDirectories.Add( fbd.SelectedPath );
+                DisplayProject();
+            }
+        }
+
+        #endregion
+
+        #region Include Dirs
+
+        private void include_AddDirectory_Click(object sender, EventArgs e)
+        {
+            ParseProject();
+            FolderBrowserDialog fbd = new FolderBrowserDialog();
+            if (fbd.ShowDialog() == DialogResult.OK)
+            {
+                _project.IncludeDirectories.Add(fbd.SelectedPath);
+                DisplayProject();
+            }
+        }
+
+        #endregion
+
+        #region File Menu
+
+        private string _filter = "Header Hero (*.header_hero)|*.header_hero";
+
+        private void saveProjectToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (_file == null)
+            {
+                SaveFileDialog sfd = new SaveFileDialog();
+                sfd.Filter = _filter;
+                if (sfd.ShowDialog() == DialogResult.OK)
+                    _file = sfd.FileName;
+            }
+
+            if (_file == null)
+                return;
+
+            Properties.Settings.Default.LastProject = _file;
+            ParseProject();
+            Sjson.Save(JsonSerializer.Save(_project), _file);
+            MarkSave();
+        }
+
+        private void MarkSave()
+        {
+            if (_file != null)
+                Text = "Header Hero - " + _file;
+            else
+                Text = "Header Hero";
+            _last_save = Sjson.Encode( JsonSerializer.Save(_project) );
+        }
+
+        private bool CheckSave()
+        {
+            ParseProject();
+            if (_last_save == Sjson.Encode(JsonSerializer.Save(_project)))
+                return true;
+            saveProjectToolStripMenuItem_Click(null, null);
+            return true;
+        }
+
+        private void newProjectToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (CheckSave())
+            {
+                _file = null;
+                _project = new Data.Project();
+                DisplayProject();
+                MarkSave();
+            }
+        }
+
+        private void closeProjectToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            newProjectToolStripMenuItem_Click(sender, e);
+        }
+
+        private void Open(string path)
+        {
+            _file = path;
+            Properties.Settings.Default.LastProject = _file;
+            _project = new Data.Project();
+            JsonSerializer.Load(_project, Sjson.Load(_file));
+            MarkSave();
+            DisplayProject();
+        }
+
+        private void openProjectToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            if (CheckSave())
+            {
+                OpenFileDialog ofd = new OpenFileDialog();
+                ofd.Filter = _filter;
+                if (ofd.ShowDialog() == DialogResult.OK)
+                    Open(ofd.FileName);
+            }
+
+        }
+
+        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            Properties.Settings.Default.Save();
+            if (!CheckSave())
+                e.Cancel = true;
+        }
+
+        #endregion
+
+        #region Scan Menu
+
+        private void scanToolStripMenuItem1_Click(object sender, EventArgs e)
+        {
+            ParseProject();
+            Parser.Scanner scanner = new Parser.Scanner(_project);
+            
+            DateTime started = DateTime.Now;
+            ProgressDialog d = new ProgressDialog();
+            d.Text = "Scanning source files...";
+            d.Work = (feedback) => scanner.Rescan(feedback);
+            d.Start();
+            _project.LastScan = started;
+
+            DisplayProject();
+
+            ReportForm rf = new ReportForm(_project, scanner);
+            rf.Show();
+        }
+
+        private void cleanRescanToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            _project.Clean();
+            scanToolStripMenuItem1_Click(sender, e);
+        }
+
+        #endregion
+    }
+}

header_hero/Windows/MainForm.resx