context: // IldasmTask.cs
  //
  // Giuseppe Greco <giuseppe.greco@agamura.com>
  // Copyright (C) 2004 Agamura, Inc.
  //
  // This program is free software; you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation; either version 2 of the License, or
  // (at your option) any later version.
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  //
  // Giuseppe Greco (giuseppe.greco@agamura.com)
  
  using System.Globalization;
  using System.IO;
  using NAnt.Core;
  using NAnt.Core.Attributes;
  using NAnt.Core.Tasks;
  using NAnt.Core.Types;
  using NAnt.Core.Util;
  
  namespace NAnt.MSNet.Tasks {
      /// <summary>
      /// Disassembles any portable executable (PE) file that contains
      /// intermediate language (IL) code.
      /// </summary>
      /// <remarks>
      ///   <para>
      ///   Files are only disassembled if the input file is newer than the output
      ///   file, or if the output file does not exist.  However, you can 
      ///   explicitly force files to be disassembled with the 
      ///   <see cref="ForceRebuild" /> attribute.
      ///   </para>
      ///   <para>
      ///   A <see cref="FileSet" /> can be used to select files to disassemble. 
      ///   To use a <see cref="FileSet" />, the <see cref="ToDirectory" /> 
      ///   attribute must be set. The file name of the output file will be equal 
      ///   to the file name of the input file, but with extension &quot;.il&quot;.
      ///   </para>
      /// </remarks>
      /// <example>
      ///   <para>
      ///   Disassembles <c>helloworld.exe</c> to <c>helloworld.il</c>.
      ///   </para>
      ///   <code>
      ///     <![CDATA[
      /// <ildasm input="helloworld.exe" output="helloworld.il" />
      ///     ]]>
      ///   </code>
      /// </example>
      /// <example>
      ///   <para>
      ///   Disassembles a set of PE files into the specified directory.
      ///   </para>
      ///   <code>
      ///     <![CDATA[
      /// <ildasm todir=".">
      ///     <assemblies>
      ///         <include name="*.exe" />
      ///         <include name="*.dll" />
      ///     </assemblies>
      /// </ildasm>
      ///     ]]>
      ///   </code>
      /// </example>
      [TaskName("ildasm")]
      [ProgramLocation(LocationType.FrameworkSdkDir)]
      public class IldasmTask : ExternalProgramBase {
          private const string _TargetExt = "il";
          private bool _all;
          private bool _bytes;
          private bool _forceRebuild;
          private bool _header;
          private bool _lineNumbers;
          private bool _noIL;
          private bool _publicOnly;
          private bool _quoteAllNames;
          private bool _rawExceptionHandling;
          private bool _source;
          private bool _tokens;
          private bool _unicode;
          private bool _utf8;
          private string _item;
          private string _visibility;
          private DirectoryInfo _toDir;
          private FileInfo _inputFile;
          private FileInfo _outputFile;
          private FileSet _assemblies;
          private string _options;
          /// <summary>
          /// Specifies whether or not the disassembler should combine the
          /// <c>/HEADER</c>, <c>/BYTE</c>, and <c>/TOKENS</c> options. The default 
          /// is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if the disassembler should combine the
          /// <c>/HEADER</c>, <c>/BYTE</c>, and <c>/TOKENS</c> options;
          /// otherwise, <see langword="false" />. The default is
          /// <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/ALL</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("all")]
          [BooleanValidator()]
          public bool All {
              get { return _all; }
              set { _all = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should generate the
          /// IL stream bytes (in hexadecimal notation) as instruction comments.
          /// The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if the IL stream bytes should be generated
          /// as instruction comments; otherwise, <see langword="false" />. The
          /// default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/BYTE</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("bytes")]
          [BooleanValidator()]
          public bool Bytes {
              get { return _bytes; }
              set { _bytes = value; }
          }
  
          /// <summary>
          /// Instructs NAnt to rebuild the output file regardless of the file
          /// timestamps. The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if the output file should be rebuilt
          /// regardless of its timestamps; otherwise <see langword="false" />.
          /// The default is <see langword="false" />.
          /// </value>
          [TaskAttribute("rebuild")]
          [BooleanValidator()]
          public bool ForceRebuild {
              get { return _forceRebuild; }
              set { _forceRebuild = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should include PE header
          /// information and runtime header information in the output. The default 
          /// is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if PE header information and runtime header
          /// information should be included in the output; otherwise,
          /// <see langword="false" />. The default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/HEADER</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("header")]
          [BooleanValidator()]
          public bool Header {
              get { return _header; }
              set { _header = value; }
          }
  
          /// <summary>
          /// Specifies the PE file to disassemble.
          /// </summary>
          /// <value>
          /// A <see cref="System.IO.FileInfo" /> that represents the PE file
          /// to disassemble.
          /// </value>
          [TaskAttribute("input", Required=false)]
          public FileInfo InputFile {
              get { return _inputFile; }
              set { _inputFile = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should include
          /// references to original source lines. The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if references to original source lines
          /// should be included; otherwise, <see langword="false" />. The
          /// default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/LINENUM</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("linenumbers")]
          [BooleanValidator()]
          public bool LineNumbers {
              get { return _lineNumbers; }
              set { _lineNumbers = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should suppress ILASM
          /// code output. The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if ILASM code output should be suppresses;
          /// otherwise, <see langword="false" />. The default is
          /// <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/NOIL</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("noil")]
          [BooleanValidator()]
          public bool NoIL {
              get { return _noIL; }
              set { _noIL = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should disassemble
          /// public items only. This is a shortcut for <see cref="Visibility" />="pub".
          /// The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if only public items should be
          /// disassembled; otherwise, <see langword="false" />. The default is
          /// <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/PUBONLY</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("publiconly")]
          [BooleanValidator()]
          public bool PublicOnly {
              get { return _publicOnly; }
              set { _publicOnly = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should enclose all names
          /// in single quotation marks. By default, only names that don't match
          /// the ILASM definition of a simple name are quoted. The default is 
          /// <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if all names should be enclosed in single
          /// quotation marks; otherwise, <see langword="false" />. The default
          /// is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/QUOTEALLNAMES</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("quoteallnames")]
          [BooleanValidator()]
          public bool QuoteAllNames {
              get { return _quoteAllNames; }
              set { _quoteAllNames = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should generate
          /// structured exception handling clauses in canonical (label) form.
          /// The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if structured exception handling clauses
          /// should be generated in canonical form; otherwise,
          /// <see langword="false" />. The default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/RAWEH</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("rawexceptionhandling")]
          [BooleanValidator()]
          public bool RawExceptionHandling {
              get { return _rawExceptionHandling; }
              set { _rawExceptionHandling = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should generate
          /// original source lines as comments. The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if original source lines should be
          /// generated as comments; otherwise, <see langword="false" />.
          /// The default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/SOURCE</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("source")]
          [BooleanValidator()]
          public bool Source {
              get { return _source; }
              set { _source = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should generate metadata
          /// token values as comments. The default is <see langword="false" />.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if metadata token values should be
          /// generated as comments; otherwise, <see langword="false" />. The
          /// default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/TOKENS</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("tokens")]
          [BooleanValidator()]
          public bool Tokens {
              get { return _tokens; }
              set { _tokens = value; }
          }
  
          /// <summary>
          /// Specifies whether or not the disassembler should use the UNICODE
          /// encoding when generating the output. The default is ANSI.
          /// </summary>
          /// <value>
          /// <see langword="true" /> if the output should be generated using
          /// the UNICODE encoding; otherwise, <see langword="false" />. The
          /// default is <see langword="false" />.
          /// </value>
          /// <remarks>
          /// <para>
          /// Corresponds to the <c>/UNICODE</c> flag.
          /// </para>
          /// </remarks>
          [TaskAttribute("unicode")]
          [BooleanValidator()]
          public bool Unicode {
              get { return _unicode; }
  
gt:             set { _unicode = value; }