internal static void Main(string[] args)
        {
            string       inputFile = null;
            WorksheetDef worksheet = new WorksheetDef {
                Index = 1
            };
            bool headers = false;

            string[]     columnNames   = null;
            FormatType[] columnFormats = null;
            string       dateFormat    = null;
            string       wikiurl       = null;
            string       username      = null;
            string       password      = null;
            string       pagePrefix    = null;
            string       tableTitle    = null;
            string       titleColumn   = null;

            string[]     pageColumnNames = null;
            FormatType[] pageFormats     = null;
            bool         overwrite       = false;
            bool         noTable         = false;
            bool         noPages         = false;
            bool         testLogin       = false;
            string       editSummary     = "Modified by exceltowiki";
            CellRange    range           = null;

            try
            {
                for (int i = 0; i < args.Length; ++i)
                {
                    string arg = args[i];
                    switch (arg)
                    {
                    case "--columns":
                        columnNames = GetColumnNames(GetArg(args, ++i));
                        break;

                    case "--formats":
                        columnFormats = GetColumnFormats(GetArg(args, ++i));
                        break;

                    case "--headers":
                        headers = true;
                        break;

                    case "--date-format":
                        dateFormat = GetDateFormat(GetArg(args, ++i));
                        break;

                    case "--worksheet":
                        worksheet = GetWorksheet(GetArg(args, ++i));
                        break;

                    case "--worksheet-range":
                        range = new CellRange(GetArg(args, ++i));
                        break;

                    case "--wiki":
                        wikiurl = GetUrl((GetArg(args, ++i)));
                        break;

                    case "--username":
                        username = GetUsername(GetArg(args, ++i));
                        break;

                    case "--password":
                        password = GetPassword(GetArg(args, ++i));
                        break;

                    case "--table-title":
                        tableTitle = GetTitle(GetArg(args, ++i));
                        break;

                    case "--title-column":
                        titleColumn = GetTitleColumn(GetArg(args, ++i));
                        break;

                    case "--page-prefix":
                        pagePrefix = GetPagePrefix(GetArg(args, ++i));
                        break;

                    case "--page-columns":
                        pageColumnNames = GetColumnNames(GetArg(args, ++i));
                        break;

                    case "--page-format":
                        pageFormats = GetColumnFormats(GetArg(args, ++i));
                        break;

                    case "--overwrite":
                        overwrite = true;
                        break;

                    case "--no-table":
                        noTable = true;
                        break;

                    case "--no-pages":
                        noPages = true;
                        break;

                    case "--test-login":
                        testLogin = true;
                        break;

                    case "--edit-summary":
                        editSummary = GetEditSummary(GetArg(args, ++i));
                        break;

                    case "--help":
                        Usage();
                        return;

                    case "--version":
                        Version();
                        return;

                    default:
                        if (String.IsNullOrEmpty(arg))
                        {
                            throw new ApplicationException("Null argument seen on command line.");
                        }
                        if (arg[0] == '-')
                        {
                            throw new ApplicationException($"Unrecognized switch argument {arg} seen.");
                        }
                        if (inputFile == null)
                        {
                            inputFile = arg;
                        }
                        else
                        {
                            throw new ApplicationException($"Extraneous argument {arg} seen.");
                        }
                        break;
                    }
                }
                worksheet.Range = range;
                bool wikiOut = wikiurl != null;
                WikiAdaptor.WikiAdaptor wiki = null;
                if (testLogin)
                {
                    if (!wikiOut)
                    {
                        throw new ArgumentException("Test login needs a wiki url specified as well as username and password");
                    }
                    if (username == null | password == null)
                    {
                        throw new ArgumentException("Test login needs both username and password arguments");
                    }
                    wiki = new WikiAdaptor.WikiAdaptor(wikiurl);
                    wiki.Login(username, password).Wait();
                    WriteError("Login successful!");
                    return;
                }
                if (inputFile == null)
                {
                    throw new ApplicationException("Missing input file argument.");
                }
                if (!File.Exists(inputFile))
                {
                    throw new ApplicationException($"Input file '{inputFile}' does not exist.");
                }
                if (wikiOut && (username == null | password == null))
                {
                    throw new ArgumentException("Both username and password must be specified for a wiki desination");
                }
                if (wikiOut && tableTitle == null)
                {
                    throw new ArgumentException("The table title must be specified for a wiki destination");
                }
                if ((pageColumnNames != null || pageFormats != null) && titleColumn == null)
                {
                    throw new ArgumentException("Column title must be specified if wiki pages are to be created.");
                }
                if (wikiOut)
                {
                    wiki = new WikiAdaptor.WikiAdaptor(wikiurl);
                    wiki.Login(username, password).Wait();
                }
                ConvertExcelToWiki(inputFile, wiki, worksheet, columnNames, columnFormats, dateFormat, headers,
                                   noTable, noPages, overwrite, tableTitle, titleColumn, pagePrefix, pageColumnNames, pageFormats, editSummary);
                if (wikiOut)
                {
                    wiki.Dispose();
                }
            }
            catch (AggregateException exs)
            {
                WriteError(exs);
            }
            catch (Exception ex)
            {
                WriteError(ex);
            }
        }
 internal static void ConvertExcelToWiki(string inputFile, WikiAdaptor.WikiAdaptor wiki, WorksheetDef worksheetDef, string[] columnNames, FormatType[] columnFormats, string dateFormat, bool headers,
                                         bool noTable, bool noPages, bool overwrite, string tableTitle, string titleColumn, string pagePrefix, string[] pageColumnNames, FormatType[] pageColumnFormats,
                                         string editSummary)
 {
     try
     {
         bool         wikiOut      = wiki != null;
         TextWriter   writer       = Console.Out;
         MemoryStream outputStream = null;
         if (wikiOut)
         {
             outputStream = new MemoryStream();
             writer       = new StreamWriter(outputStream);
         }
         string path = inputFile;
         if (!Path.IsPathRooted(path))
         {
             path = Path.Combine(Directory.GetCurrentDirectory(), inputFile);
         }
         using (WorkbookAdaptor workbook = WorkbookAdaptor.Open(path, true))
         {
             WorksheetAdaptor worksheet = workbook.GetWorksheet(worksheetDef.Reference);
             if (worksheet != null)
             {
                 CellRange range    = worksheetDef.Range;
                 int       nrows    = worksheet.RowCount;
                 int       ncolumns = worksheet.ColumnCount;
                 int       row1     = 1;
                 int       column1  = 1;
                 if (range != null)
                 {
                     nrows    = range.GetRowCount();
                     ncolumns = range.GetColumnCount();
                     row1     = range.ULCell.Row;
                     column1  = range.ULCell.ColumnIndex;
                 }
                 if (nrows == 0)
                 {
                     throw new ApplicationException("The source table is empty.");
                 }
                 ColumnDef[] columns = GetColumns(column1, ncolumns, columnNames, columnFormats, dateFormat);
                 if (!noTable)
                 {
                     WriteError("Writing table...");
                     writer.WriteLine("{| class=\"wikitable\"");
                     for (int rowIndex = row1; rowIndex <= nrows; ++rowIndex)
                     {
                         if (headers && rowIndex == row1)
                         {
                             writer.WriteLine("|+");
                             foreach (var column in columnNames)
                             {
                                 string s = worksheet.Cells(rowIndex, column).ToString();
                                 writer.WriteLine("|" + s);
                             }
                         }
                         else
                         {
                             WriteError($"\rWriting table row {rowIndex} of {nrows}.", false);
                             writer.WriteLine("|-");
                             for (int i = 0; i < columns.Length; ++i)
                             {
                                 string column = columns[i].Name;
                                 string s      = worksheet.Cells(rowIndex, column).ToString();
                                 string s1     = FormatColumn(s, columns[i]);
                                 if (column == titleColumn)
                                 {
                                     writer.WriteLine("|" + GetPageLink(pagePrefix, s1));
                                 }
                                 else
                                 {
                                     writer.WriteLine("|" + s1);
                                 }
                             }
                         }
                     }
                     WriteError(" Finished.");
                 }
                 else
                 {
                     WriteError("Skipping table creation");
                 }
                 if (wikiOut)
                 {
                     writer.Flush();
                     outputStream.Position = 0L;
                     ColumnDef[] pageColumns = GetColumns(column1, ncolumns, pageColumnNames, pageColumnFormats, dateFormat);
                     if (!noTable)
                     {
                         try
                         {
                             wiki.CreatePage(tableTitle, editSummary, outputStream, overwrite).Wait();
                             WriteError($"Created wiki table {tableTitle}");
                         }
                         catch (AggregateException exs)
                         {
                             WriteError(exs);
                         }
                         catch (Exception ex)
                         {
                             WriteError("*Warning* Unable to create wiki table: " + ex.Message);
                         }
                     }
                     if (titleColumn != null && !noPages)
                     {
                         Dictionary <string, string> sectionTitles = new Dictionary <string, string>();
                         for (int rowIndex = row1; rowIndex <= nrows; ++rowIndex)
                         {
                             if (headers && rowIndex == row1)
                             {
                                 foreach (var column in pageColumnNames)
                                 {
                                     string s = worksheet.Cells(rowIndex, column).ToString();
                                     if (!String.IsNullOrEmpty(s))
                                     {
                                         sectionTitles[column] = s.Trim();
                                     }
                                 }
                             }
                             else
                             {
                                 HashSet <string> titles = new HashSet <string>();
                                 string           title  = worksheet.Cells(rowIndex, titleColumn).ToString();
                                 if (WikiSupport.IsValidTitle(title))
                                 {
                                     if (!titles.Contains(title))
                                     {
                                         titles.Add(title);
                                         StringBuilder sb = new StringBuilder();
                                         for (int i = 0; i < pageColumns.Length; ++i)
                                         {
                                             string column = pageColumns[i].Name;
                                             if (sectionTitles.TryGetValue(column, out string sectionTitle))
                                             {
                                                 sb.AppendLine($"=={sectionTitle}==");
                                                 sb.AppendLine();
                                             }
                                             string s  = worksheet.Cells(rowIndex, column).ToString();
                                             string s1 = FormatColumn(s, pageColumns[i]);
                                             sb.AppendLine(s1);
                                         }
                                         try
                                         {
                                             wiki.CreatePage(GetPageTitle(pagePrefix, title), editSummary, sb.ToString(), overwrite).Wait();
                                             WriteError($"Created page {title}");
                                         }
                                         catch (AggregateException exs)
                                         {
                                             WriteError($"Unable to create wiki page from row {rowIndex}");
                                             WriteError(exs);
                                         }
                                         catch (Exception ex)
                                         {
                                             WriteError($"Unable to create wiki page from row {rowIndex}: {ex.Message}");
                                         }
                                     }
                                     else
                                     {
                                         WriteError($"Duplicate wiki page title {title} at row {rowIndex}...skipping");
                                     }
                                 }
                                 else
                                 {
                                     WriteError($"Invalid wiki page title {title} at row {rowIndex}...skipping.");
                                 }
                             }
                         }
                     }
                 }
             }
             else
             {
                 throw new ApplicationException("Worksheet not found");
             }
         }
     }
     catch (Exception ex)
     {
         throw new ApplicationException("Unable to convert excel to wiki", ex);
     }
 }