static void Main(string[] args)
        {
            //Holds all of the argument paths we may get given
            ArgHolder pathArg = new ArgHolder();
            ArgHolder interfaceArg = new ArgHolder();
            ArgHolder serviceArg = new ArgHolder();
            ArgHolder proxyArg = new ArgHolder();
            ArgHolder contractArg = new ArgHolder();
            ArgHolder wcfserviceArg = new ArgHolder();
            ArgHolder hostArg = new ArgHolder();

            bool bVerbose = false; //Verbosity level
            bool bOutputSpecified = false; //Whether any output values have been set

            #region argParsing
            for (int i = 0; i < args.Length; i++)
            {
                string arg = args[i].ToLower();
                ArgHolder holder = null;

                if (arg.StartsWith("--")) // If long param
                {
                    switch(arg)
                    {
                        case "--path":
                            holder = pathArg;
                            break;
                        case "--interface":
                            holder = interfaceArg;
                            break;
                        case "--service":
                            holder = serviceArg;
                            break;
                        case "--proxy":
                            holder = proxyArg;
                            break;
                        case "--contract":
                            holder = contractArg;
                            break;
                        case "--wcfservice":
                            holder = wcfserviceArg;
                            break;
                        case "--host":
                            holder = hostArg;
                            break;
                        case "--verbose":
                            bVerbose = true;
                            break;
                        default:
                            Console.Error.WriteLine(args[i] + " not a valid argument");
                            break;
                    }
                } // Ends if long param
                else if (arg.StartsWith("-")) // Else if short param
                {
                    switch(arg)
                    {
                        case "-p":
                            holder = pathArg;
                            break;
                        case "-i":
                            holder = interfaceArg;
                            break;
                        case "-s":
                            holder = serviceArg;
                            break;
                        case "-x":
                            holder = proxyArg;
                            break;
                        case "-c":
                            holder = contractArg;
                            break;
                        case "-w":
                            holder = wcfserviceArg;
                            break;
                        case "-h":
                            holder = hostArg;
                            break;
                        case "-v":
                            bVerbose = true;
                            break;
                        default:
                            Console.Error.WriteLine(args[i] + " not a valid argument");
                            break;
                    }
                } // Ends else if short param
                else
                {
                    if (arg == "/?")
                    {
                        Usage();
                    }
                    else
                    {
                        Console.Error.WriteLine(args[i] + " not a valid argument");
                    }
                }

                //If given a parameter that comes as two args, i.e. arg & path, consume an extra arg this loop
                if (holder != null)
                {
                    i++;
                    if (i >= args.Length)
                    {
                        Console.Error.WriteLine(string.Format("Insufficient number of arguments provided."));
                        Usage();
                    }
                    holder.Arg = args[i];
                    if (holder != pathArg)
                    {
                        bOutputSpecified = true;
                    }
                }
            } // Ends loop over args
            #endregion argParsing

            // Check we were given an input file at least
            if (pathArg.Arg == null)
            {
                System.Console.Error.WriteLine("No input path specified");
                Usage();
            }

            // If no output parameters specified, just spit out all code to default files
            if (!bOutputSpecified)
            {
                interfaceArg.Arg = DefaultInterfaceFile;
                serviceArg.Arg = DefaultImplementationFile;
                proxyArg.Arg = DefaultProxyFile;
                contractArg.Arg = DefaultContractFile;
                wcfserviceArg.Arg = DefaultWCFServiceFile;
                hostArg.Arg = DefaultHostFile;
            } // Ends if no output parameters specified

            #region outputWriters
            // Initialise all writers to null
            TextWriter writerInterface = null;
            TextWriter writerService = null;
            TextWriter writerProxy = null;
            TextWriter writerContract = null;
            TextWriter writerWCFService = null;
            TextWriter writerHost = null;

            //Lets us print out info in exceptions if anything goes wrong
            string exceptionInfoString = "";
            string givenArg = "";
            //try-catch-bail
            try
            {
                //try-catch-info-throw
                try
                {
                    //Only open the files we've been told to care about
                    //i.e. We need to prevent any ArgumentNullExceptions as it's a valid use case
                    exceptionInfoString = "Service Interface";
                    givenArg = interfaceArg.Arg;
                    if (givenArg != null) writerInterface = new StreamWriter(givenArg);

                    exceptionInfoString = "Service Implementation";
                    givenArg = serviceArg.Arg;
                    if (givenArg != null) writerService = new StreamWriter(givenArg);

                    exceptionInfoString = "Client Proxy";
                    givenArg = proxyArg.Arg;
                    if (givenArg != null) writerProxy = new StreamWriter(givenArg);

                    exceptionInfoString = "WCF Contract";
                    givenArg = contractArg.Arg;
                    if (givenArg != null) writerContract = new StreamWriter(givenArg);

                    exceptionInfoString = "WCF Service";
                    givenArg = wcfserviceArg.Arg;
                    if (givenArg != null) writerWCFService = new StreamWriter(givenArg);

                    exceptionInfoString = "WCF Host";
                    givenArg = hostArg.Arg;
                    if (givenArg != null) writerHost = new StreamWriter(givenArg);
                }
                catch (System.ArgumentException sae)
                {
                    System.Console.Error.WriteLine("Bad output path {0} given for {1}", givenArg, exceptionInfoString);
                    throw sae;
                }
                catch (System.UnauthorizedAccessException uae)
                {
                    System.Console.Error.WriteLine("Unauthorised access to {0} given for {1}", givenArg, exceptionInfoString);
                    throw uae;
                }
                catch (System.IO.DirectoryNotFoundException dnfe)
                {
                    System.Console.Error.WriteLine("Invalid directory in path {0} given for {1}", givenArg, exceptionInfoString);
                    throw dnfe;
                }
                catch (System.IO.PathTooLongException ptle)
                {
                    System.Console.Error.WriteLine("The specified path, file name, or both in {0} given for {1}, exceeds the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.", givenArg, exceptionInfoString);
                    throw ptle;
                }
                catch (Exception ex)
                {
                    System.Console.Error.Write(ex.ToString()); //Cover any missed bases
                    throw ex;
                }//End try-catch-info-throw
            }
            catch (Exception)
            {
                Environment.Exit(0);
            }//End try-catch-bail

            //May be that we're being watched by a debugger and need to output in two directions at once
            if (System.Diagnostics.Debugger.IsAttached)
            {
                TextWriter writerDebug = new TextWriterDebug();
                writerInterface = writerInterface != null ? new TextWriterMulti(writerInterface, writerDebug) : null;
                writerService = writerService != null ? new TextWriterMulti(writerService, writerDebug) : null;
                writerProxy = writerProxy != null ? new TextWriterMulti(writerProxy, writerDebug) : null;
                writerContract = writerContract != null ? new TextWriterMulti(writerContract, writerDebug) : null;
                writerWCFService = writerWCFService != null ? new TextWriterMulti(writerWCFService, writerDebug) : null;
                writerHost = writerHost != null ? new TextWriterMulti(writerHost, writerDebug) : null;
            }

            TextWriters textwriters = new TextWriters
            {
                writerInterface = writerInterface,
                writerService = writerService,
                writerProxy = writerProxy,
                writerWCFContracts = writerContract,
                writerWCFService = writerWCFService,
                writerWCFHost = writerHost
            };
            #endregion outputWriters

            //Output info if in verbose
            if (bVerbose)
            {
                System.Console.WriteLine(string.Format("// IDL input path: \"{0}\"", pathArg.Arg));
                System.Diagnostics.Debug.WriteLine(string.Format("// IDL input path: \"{0}\"", pathArg.Arg));

                foreach (TextWriter textwriter in textwriters.GenTextWriters())
                {
                    if(textwriter != null)
                    {
                        System.Console.WriteLine(string.Format("// Output path: \"{0}\"", ((FileStream)((StreamWriter)textwriter).BaseStream).Name));
                        System.Diagnostics.Debug.WriteLine(string.Format("// Output path: \"{0}\"", ((FileStream)((StreamWriter)textwriter).BaseStream).Name));
                    }
                }
            }

            System.Xml.XmlReaderSettings readerSettings = new System.Xml.XmlReaderSettings();
            readerSettings.DtdProcessing = System.Xml.DtdProcessing.Ignore;
            readerSettings.ValidationType = ValidationType.None;
            readerSettings.ConformanceLevel = System.Xml.ConformanceLevel.Auto;
            readerSettings.CloseInput = true;

            //Try to open the input xml file and generate the output code
            try
            {
                try
                {
                    if (pathArg.Arg != null) BuildCodeFromDbusIDL(XmlReader.Create(pathArg.Arg, readerSettings), textwriters);
                }
                catch (System.IO.FileNotFoundException fne)
                {
                    System.Console.Error.WriteLine("Could not find the input file {0}", pathArg.Arg);
                    throw fne;
                }
                catch (System.UriFormatException ufe)
                {
                    System.Console.Error.WriteLine("URI Formatting exception for input file {0}", pathArg.Arg);
                    throw ufe;
                }
            }
            catch (Exception)
            {
                Environment.Exit(0);
            }

            //Close everything
            textwriters.Close();

            //If debugger attached, wait for them to tell us to quit
            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.WriteLine("Press a key to continue...");
                Console.ReadKey(true);
            }
        }
        static void Main(string[] args)
        {
            //Holds all of the argument paths we may get given
            ArgHolder pathArg       = new ArgHolder();
            ArgHolder interfaceArg  = new ArgHolder();
            ArgHolder serviceArg    = new ArgHolder();
            ArgHolder proxyArg      = new ArgHolder();
            ArgHolder contractArg   = new ArgHolder();
            ArgHolder wcfserviceArg = new ArgHolder();
            ArgHolder hostArg       = new ArgHolder();

            bool bVerbose         = false; //Verbosity level
            bool bOutputSpecified = false; //Whether any output values have been set

            #region argParsing
            for (int i = 0; i < args.Length; i++)
            {
                string    arg    = args[i].ToLower();
                ArgHolder holder = null;

                if (arg.StartsWith("--")) // If long param
                {
                    switch (arg)
                    {
                    case "--path":
                        holder = pathArg;
                        break;

                    case "--interface":
                        holder = interfaceArg;
                        break;

                    case "--service":
                        holder = serviceArg;
                        break;

                    case "--proxy":
                        holder = proxyArg;
                        break;

                    case "--contract":
                        holder = contractArg;
                        break;

                    case "--wcfservice":
                        holder = wcfserviceArg;
                        break;

                    case "--host":
                        holder = hostArg;
                        break;

                    case "--verbose":
                        bVerbose = true;
                        break;

                    default:
                        Console.Error.WriteLine(args[i] + " not a valid argument");
                        break;
                    }
                } // Ends if long param
                else if (arg.StartsWith("-")) // Else if short param
                {
                    switch (arg)
                    {
                    case "-p":
                        holder = pathArg;
                        break;

                    case "-i":
                        holder = interfaceArg;
                        break;

                    case "-s":
                        holder = serviceArg;
                        break;

                    case "-x":
                        holder = proxyArg;
                        break;

                    case "-c":
                        holder = contractArg;
                        break;

                    case "-w":
                        holder = wcfserviceArg;
                        break;

                    case "-h":
                        holder = hostArg;
                        break;

                    case "-v":
                        bVerbose = true;
                        break;

                    default:
                        Console.Error.WriteLine(args[i] + " not a valid argument");
                        break;
                    }
                } // Ends else if short param
                else
                {
                    if (arg == "/?")
                    {
                        Usage();
                    }
                    else
                    {
                        Console.Error.WriteLine(args[i] + " not a valid argument");
                    }
                }

                //If given a parameter that comes as two args, i.e. arg & path, consume an extra arg this loop
                if (holder != null)
                {
                    i++;
                    if (i >= args.Length)
                    {
                        Console.Error.WriteLine(string.Format("Insufficient number of arguments provided."));
                        Usage();
                    }
                    holder.Arg = args[i];
                    if (holder != pathArg)
                    {
                        bOutputSpecified = true;
                    }
                }
            } // Ends loop over args
            #endregion argParsing

            // Check we were given an input file at least
            if (pathArg.Arg == null)
            {
                System.Console.Error.WriteLine("No input path specified");
                Usage();
            }

            // If no output parameters specified, just spit out all code to default files
            if (!bOutputSpecified)
            {
                interfaceArg.Arg  = DefaultInterfaceFile;
                serviceArg.Arg    = DefaultImplementationFile;
                proxyArg.Arg      = DefaultProxyFile;
                contractArg.Arg   = DefaultContractFile;
                wcfserviceArg.Arg = DefaultWCFServiceFile;
                hostArg.Arg       = DefaultHostFile;
            } // Ends if no output parameters specified

            #region outputWriters
            // Initialise all writers to null
            TextWriter writerInterface  = null;
            TextWriter writerService    = null;
            TextWriter writerProxy      = null;
            TextWriter writerContract   = null;
            TextWriter writerWCFService = null;
            TextWriter writerHost       = null;

            //Lets us print out info in exceptions if anything goes wrong
            string exceptionInfoString = "";
            string givenArg            = "";
            //try-catch-bail
            try
            {
                //try-catch-info-throw
                try
                {
                    //Only open the files we've been told to care about
                    //i.e. We need to prevent any ArgumentNullExceptions as it's a valid use case
                    exceptionInfoString = "Service Interface";
                    givenArg            = interfaceArg.Arg;
                    if (givenArg != null)
                    {
                        writerInterface = new StreamWriter(givenArg);
                    }

                    exceptionInfoString = "Service Implementation";
                    givenArg            = serviceArg.Arg;
                    if (givenArg != null)
                    {
                        writerService = new StreamWriter(givenArg);
                    }

                    exceptionInfoString = "Client Proxy";
                    givenArg            = proxyArg.Arg;
                    if (givenArg != null)
                    {
                        writerProxy = new StreamWriter(givenArg);
                    }

                    exceptionInfoString = "WCF Contract";
                    givenArg            = contractArg.Arg;
                    if (givenArg != null)
                    {
                        writerContract = new StreamWriter(givenArg);
                    }

                    exceptionInfoString = "WCF Service";
                    givenArg            = wcfserviceArg.Arg;
                    if (givenArg != null)
                    {
                        writerWCFService = new StreamWriter(givenArg);
                    }

                    exceptionInfoString = "WCF Host";
                    givenArg            = hostArg.Arg;
                    if (givenArg != null)
                    {
                        writerHost = new StreamWriter(givenArg);
                    }
                }
                catch (System.ArgumentException sae)
                {
                    System.Console.Error.WriteLine("Bad output path {0} given for {1}", givenArg, exceptionInfoString);
                    throw sae;
                }
                catch (System.UnauthorizedAccessException uae)
                {
                    System.Console.Error.WriteLine("Unauthorised access to {0} given for {1}", givenArg, exceptionInfoString);
                    throw uae;
                }
                catch (System.IO.DirectoryNotFoundException dnfe)
                {
                    System.Console.Error.WriteLine("Invalid directory in path {0} given for {1}", givenArg, exceptionInfoString);
                    throw dnfe;
                }
                catch (System.IO.PathTooLongException ptle)
                {
                    System.Console.Error.WriteLine("The specified path, file name, or both in {0} given for {1}, exceeds the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.", givenArg, exceptionInfoString);
                    throw ptle;
                }
                catch (Exception ex)
                {
                    System.Console.Error.Write(ex.ToString()); //Cover any missed bases
                    throw ex;
                }//End try-catch-info-throw
            }
            catch (Exception)
            {
                Environment.Exit(0);
            }//End try-catch-bail

            //May be that we're being watched by a debugger and need to output in two directions at once
            if (System.Diagnostics.Debugger.IsAttached)
            {
                TextWriter writerDebug = new TextWriterDebug();
                writerInterface  = writerInterface != null ? new TextWriterMulti(writerInterface, writerDebug) : null;
                writerService    = writerService != null ? new TextWriterMulti(writerService, writerDebug) : null;
                writerProxy      = writerProxy != null ? new TextWriterMulti(writerProxy, writerDebug) : null;
                writerContract   = writerContract != null ? new TextWriterMulti(writerContract, writerDebug) : null;
                writerWCFService = writerWCFService != null ? new TextWriterMulti(writerWCFService, writerDebug) : null;
                writerHost       = writerHost != null ? new TextWriterMulti(writerHost, writerDebug) : null;
            }

            TextWriters textwriters = new TextWriters
            {
                writerInterface    = writerInterface,
                writerService      = writerService,
                writerProxy        = writerProxy,
                writerWCFContracts = writerContract,
                writerWCFService   = writerWCFService,
                writerWCFHost      = writerHost
            };
            #endregion outputWriters

            //Output info if in verbose
            if (bVerbose)
            {
                System.Console.WriteLine(string.Format("// IDL input path: \"{0}\"", pathArg.Arg));
                System.Diagnostics.Debug.WriteLine(string.Format("// IDL input path: \"{0}\"", pathArg.Arg));

                foreach (TextWriter textwriter in textwriters.GenTextWriters())
                {
                    if (textwriter != null)
                    {
                        System.Console.WriteLine(string.Format("// Output path: \"{0}\"", ((FileStream)((StreamWriter)textwriter).BaseStream).Name));
                        System.Diagnostics.Debug.WriteLine(string.Format("// Output path: \"{0}\"", ((FileStream)((StreamWriter)textwriter).BaseStream).Name));
                    }
                }
            }


            System.Xml.XmlReaderSettings readerSettings = new System.Xml.XmlReaderSettings();
            readerSettings.DtdProcessing    = System.Xml.DtdProcessing.Ignore;
            readerSettings.ValidationType   = ValidationType.None;
            readerSettings.ConformanceLevel = System.Xml.ConformanceLevel.Auto;
            readerSettings.CloseInput       = true;

            //Try to open the input xml file and generate the output code
            try
            {
                try
                {
                    if (pathArg.Arg != null)
                    {
                        BuildCodeFromDbusIDL(XmlReader.Create(pathArg.Arg, readerSettings), textwriters);
                    }
                }
                catch (System.IO.FileNotFoundException fne)
                {
                    System.Console.Error.WriteLine("Could not find the input file {0}", pathArg.Arg);
                    throw fne;
                }
                catch (System.UriFormatException ufe)
                {
                    System.Console.Error.WriteLine("URI Formatting exception for input file {0}", pathArg.Arg);
                    throw ufe;
                }
            }
            catch (Exception)
            {
                Environment.Exit(0);
            }

            //Close everything
            textwriters.Close();

            //If debugger attached, wait for them to tell us to quit
            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.WriteLine("Press a key to continue...");
                Console.ReadKey(true);
            }
        }