شركة التطبيقات المتكاملة لتصميم النظم البرمجية الخاصة ش.ش.و.

Integrated Applications Programming Company

Skip Navigation LinksHome » Code Library » Default

Public general use code classes and xml files that we've compiled and used over the years:

General use static class of common functions used by most applications.

   1:  using System;
   2:  using System.Collections;
   3:  using System.Collections.Generic;
   4:  using System.ComponentModel;
   5:  using System.Configuration;
   6:  using System.Data;
   7:  using System.Globalization;
   8:  using System.IO;
   9:  using System.Linq;
  10:  using System.Net;
  11:  using System.Reflection;
  12:  using System.Text;
  13:  using System.Text.RegularExpressions;
  14:  //#if WFA
  15:  //#else
  16:  using System.Web;
  17:  using System.Web.Caching;
  18:  using System.Web.UI;
  19:  using System.Web.UI.WebControls;
  20:  using System.Xml;
  21:  using System.Xml.Linq;
  22:  using static System.Net.WebRequestMethods;
  23:  //#endif
  24:   
  25:  namespace Ia.Cl.Model
  26:  {
  27:      ////////////////////////////////////////////////////////////////////////////
  28:   
  29:      /// <summary publish="true">
  30:      /// General use static class of common functions used by most applications.
  31:      /// 
  32:      /// </summary>
  33:      /// <remarks> 
  34:      /// Copyright © 2001-2019 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
  35:      ///
  36:      /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
  37:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  38:      ///
  39:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  40:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  41:      /// 
  42:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  43:      /// 
  44:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  45:      /// </remarks> 
  46:      public static class Default
  47:      {
  48:          static Random random = new Random();
  49:          // very important that you declare random here then use random.Next() elsewhere, otherwise you will have duplicate results
  50:   
  51:          ////////////////////////////////////////////////////////////////////////////
  52:   
  53:          /// <summary>
  54:          /// Splits CSV file lines
  55:          /// </summary>
  56:          public static IEnumerable<string> CsvLineSplitter(string line)
  57:          {
  58:              int fieldStart = 0;
  59:   
  60:              for (int i = 0; i < line.Length; i++)
  61:              {
  62:                  if (line[i] == ',')
  63:                  {
  64:                      yield return line.Substring(fieldStart, i - fieldStart);
  65:   
  66:                      fieldStart = i + 1;
  67:                  }
  68:   
  69:                  if (line[i] == '"') for (i++; line[i] != '"'; i++) { }
  70:              }
  71:          }
  72:   
  73:          ////////////////////////////////////////////////////////////////////////////
  74:   
  75:          /// <summary>
  76:          ///
  77:          /// </summary>
  78:          public static string Substring(string str, int len)
  79:          {
  80:              if (str.Length >= len - 3) str = str.Substring(0, len - 3) + "... ";
  81:              else if (str.Length > 0) str = str.Substring(0, str.Length);
  82:              else str = "";
  83:   
  84:              return str;
  85:          }
  86:   
  87:          ////////////////////////////////////////////////////////////////////////////
  88:   
  89:          /// <summary>
  90:          ///
  91:          /// </summary>
  92:          public static string Url(string text, string url)
  93:          {
  94:              return "<a href=" + url + ">" + text + "</a>";
  95:          }
  96:   
  97:          ////////////////////////////////////////////////////////////////////////////
  98:   
  99:          /// <summary>
 100:          ///
 101:          /// </summary>
 102:          public static string YesNo(bool checkValue)
 103:          {
 104:              string text;
 105:   
 106:              if (checkValue) text = "<span class=\"yes\">Yes</span>";
 107:              else text = "<span class=\"no\">No</span>";
 108:   
 109:              return text;
 110:          }
 111:   
 112:          ////////////////////////////////////////////////////////////////////////////
 113:   
 114:          /// <summary>
 115:          ///
 116:          /// </summary>
 117:          public static string YesNo(bool? checkValue)
 118:          {
 119:              string text;
 120:   
 121:              if (checkValue == null) text = "<span class=\"na\">NA</span>";
 122:              else if (checkValue == true) text = "<span class=\"yes\">Yes</span>";
 123:              else text = "<span class=\"no\">No</span>";
 124:   
 125:              return text;
 126:          }
 127:   
 128:          ////////////////////////////////////////////////////////////////////////////
 129:   
 130:          /// <summary>
 131:          ///
 132:          /// </summary>
 133:          public static string YesNoText(bool checkValue)
 134:          {
 135:              string text;
 136:   
 137:              if (checkValue) text = "Yes";
 138:              else text = "No";
 139:   
 140:              return text;
 141:          }
 142:   
 143:          ////////////////////////////////////////////////////////////////////////////
 144:   
 145:          /// <summary>
 146:          ///
 147:          /// </summary>
 148:          public static string YesNoInArabic(bool checkValue)
 149:          {
 150:              string text;
 151:   
 152:              if (checkValue) text = "<span class=\"yes\">نعم</span>";
 153:              else text = "<span class=\"no\">لا</span>";
 154:   
 155:              return text;
 156:          }
 157:   
 158:          ////////////////////////////////////////////////////////////////////////////
 159:   
 160:          /// <summary>
 161:          ///
 162:          /// </summary>
 163:          public static string YesNoInArabic(bool? checkValue)
 164:          {
 165:              string text;
 166:   
 167:              if (checkValue == null) text = "<span class=\"na\">لا ينطبق</span>";
 168:              else if (checkValue == true) text = "<span class=\"yes\">نعم</span>";
 169:              else text = "<span class=\"no\">لا</span>";
 170:   
 171:              return text;
 172:          }
 173:   
 174:          ////////////////////////////////////////////////////////////////////////////
 175:   
 176:          /// <summary>
 177:          ///
 178:          /// </summary>
 179:          public static string ActiveIdle(object o)
 180:          {
 181:              bool b;
 182:              string s;
 183:   
 184:              if (o != null && o.ToString().Length > 0)
 185:              {
 186:                  b = (bool)o;
 187:   
 188:                  if (b) s = "<span style=\"color:Green\">Active</span>";
 189:                  else s = "<span style=\"color:DarkGoldenRod\">Idle</span>";
 190:              }
 191:              else s = "";
 192:   
 193:              return s;
 194:          }
 195:   
 196:          ////////////////////////////////////////////////////////////////////////////
 197:   
 198:          /// <summary>
 199:          ///
 200:          /// </summary>
 201:          public static string ActiveIdleInArabic(object o)
 202:          {
 203:              bool b;
 204:              string s;
 205:   
 206:              if (o != null && o.ToString().Length > 0)
 207:              {
 208:                  b = (bool)o;
 209:   
 210:                  if (b) s = "<span style=\"color:Green\">فعال</span>";
 211:                  else s = "<span style=\"color:DarkGoldenRod\">مطفأ</span>";
 212:              }
 213:              else s = "";
 214:   
 215:              return s;
 216:          }
 217:   
 218:          ////////////////////////////////////////////////////////////////////////////
 219:          ////////////////////////////////////////////////////////////////////////////
 220:   
 221:          /// <summary>
 222:          /// Return a random number n where maxValue > n >= 0
 223:          /// <param name="maxValue">integer</param>
 224:          /// <returns>int where maxValue > n >= 0</returns>
 225:          /// </summary>
 226:          public static int Random(int maxValue)
 227:          {
 228:              return random.Next(maxValue);
 229:          }
 230:   
 231:          ////////////////////////////////////////////////////////////////////////////
 232:   
 233:          /// <summary>
 234:          /// Return a random number n, with seed, where ra > num >= 0
 235:          /// <param name="seed">integer</param>
 236:          /// <param name="ra">integer</param>
 237:          /// <returns>int where ra > num >=0</returns>
 238:          /// </summary>
 239:          public static int RandomWithSeed(int seed, int ra)
 240:          {
 241:              // return a random number num: ra > num >= 0
 242:              int num;
 243:   
 244:              num = random.Next(ra);
 245:   
 246:              return num;
 247:          }
 248:   
 249:          ////////////////////////////////////////////////////////////////////////////
 250:   
 251:          /// <summary>
 252:          /// Return a random number n where r1 > num >= r0
 253:          /// <param name="r1">integer max</param>
 254:          /// <param name="r0">integer min</param>
 255:          /// <returns>int where r1 >= num >= r0</returns>
 256:          /// </summary>
 257:          public static int Random(int r0, int r1)
 258:          {
 259:              // return a random number num: r1 >= num >= r0
 260:              int num;
 261:   
 262:              num = random.Next(r1) + r0;
 263:   
 264:              return num;
 265:          }
 266:   
 267:          ////////////////////////////////////////////////////////////////////////////
 268:   
 269:          /// <summary>
 270:          /// Return a pseudo-random item from list
 271:          /// </summary>
 272:          public static string Random(string s)
 273:          {
 274:              // take a list of comma seperated values in s and return one pseudo-random value
 275:              int n;
 276:              string[] sp;
 277:   
 278:              sp = s.Split(',');
 279:   
 280:              n = Random(sp.Length);
 281:   
 282:              return sp[n].ToString();
 283:          }
 284:   
 285:          ////////////////////////////////////////////////////////////////////////////
 286:   
 287:          /// <summary>
 288:          ///
 289:          /// </summary>
 290:          public static bool RandomBool
 291:          {
 292:              get
 293:              {
 294:                  bool b;
 295:                  int n;
 296:   
 297:                  n = random.Next(2);
 298:   
 299:                  if (n == 1) b = true;
 300:                  else b = false;
 301:   
 302:                  return b;
 303:              }
 304:          }
 305:   
 306:          ////////////////////////////////////////////////////////////////////////////
 307:   
 308:          /// <summary>
 309:          /// Return a random weighted bool value between 0 and 100
 310:          /// </summary>
 311:          public static bool RandomPercentWeightedBool(int weight)
 312:          {
 313:              bool b;
 314:   
 315:              weight = weight > 100 ? 100 : weight;
 316:              weight = weight < 0 ? 0 : weight;
 317:   
 318:              b = (random.Next(0, 100) < weight);
 319:   
 320:              return b;
 321:          }
 322:   
 323:          ////////////////////////////////////////////////////////////////////////////
 324:   
 325:          /// <summary>
 326:          /// Return a random percent value between 0 and 100
 327:          /// </summary>
 328:          public static int RandomPercent()
 329:          {
 330:              return random.Next(0, 100);
 331:          }
 332:   
 333:          ////////////////////////////////////////////////////////////////////////////
 334:   
 335:          /// <summary>
 336:          ///
 337:          /// </summary>
 338:          public static string RandomAlphanumeric(int length)
 339:          {
 340:              const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 341:   
 342:              return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
 343:          }
 344:   
 345:          ////////////////////////////////////////////////////////////////////////////
 346:   
 347:          /// <summary>
 348:          ///
 349:          /// </summary>
 350:          public static string RandomNumber(int length)
 351:          {
 352:              const string chars = "0123456789";
 353:   
 354:              return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
 355:          }
 356:   
 357:          ////////////////////////////////////////////////////////////////////////////
 358:          ////////////////////////////////////////////////////////////////////////////
 359:   
 360:          /// <summary>
 361:          ///
 362:          /// </summary>
 363:          public static List<int> RandomList(int start, int end, int count)
 364:          {
 365:              int n;
 366:              List<int> list;
 367:   
 368:              list = new List<int>();
 369:   
 370:              while (list.Count < count)
 371:              {
 372:                  n = random.Next(start, end);
 373:   
 374:                  list.Add(n);
 375:              }
 376:   
 377:              return list;
 378:          }
 379:   
 380:          ////////////////////////////////////////////////////////////////////////////
 381:   
 382:          /// <summary>
 383:          /// Return at tick + count long
 384:          /// </summary>
 385:          public static long TickAndCountId(int count)
 386:          {
 387:              return DateTime.UtcNow.AddHours(3).Ticks + count;
 388:          }
 389:   
 390:          ////////////////////////////////////////////////////////////////////////////
 391:   
 392:          /// <summary>
 393:          /// Return at second + count long
 394:          /// </summary>
 395:          public static long TickSecondAndCountId(int count)
 396:          {
 397:              return DateTimeSecond() + count;
 398:          }
 399:   
 400:          ////////////////////////////////////////////////////////////////////////////
 401:   
 402:          /// <summary>
 403:          ///
 404:          /// </summary>
 405:          public static string TickDateTime(string tick)
 406:          {
 407:              // reads a tick count and returns the date time as string
 408:              string line;
 409:   
 410:              try
 411:              {
 412:                  DateTime t = new DateTime(long.Parse(tick));
 413:                  line = t.ToString("dd/MM/yyyy HH:mm");
 414:              }
 415:              catch (Exception)
 416:              {
 417:                  line = "";
 418:              }
 419:   
 420:              return line;
 421:          }
 422:   
 423:          ////////////////////////////////////////////////////////////////////////////
 424:   
 425:          /// <summary>
 426:          ///
 427:          /// </summary>
 428:          public static long DateTimeSecond(DateTime dt)
 429:          {
 430:              // return the number of seconds (total) in datetime
 431:              long l;
 432:   
 433:              // A single tick represents one hundred nanoseconds or one ten-millionth of a second
 434:   
 435:              l = dt.Ticks / 10000000;
 436:   
 437:              return l;
 438:          }
 439:   
 440:          ////////////////////////////////////////////////////////////////////////////
 441:   
 442:          /// <summary>
 443:          /// Return the number of seconds (total) in datetime. A single tick represents one hundred nanoseconds or one ten-millionth of a second.
 444:          /// </summary>
 445:          public static int DateTimeSecond()
 446:          {
 447:              return (int)(DateTime.UtcNow.AddHours(3).Ticks / 10000000);
 448:          }
 449:   
 450:  #if WFA
 451:  #else
 452:          ////////////////////////////////////////////////////////////////////////////
 453:   
 454:          /// <summary>
 455:          ///
 456:          /// </summary>
 457:          public static void InitializeDropDownList(DropDownList ddl, DataTable source_dt, string text_field, string value_field, int selected_index)
 458:          {
 459:              int index;
 460:   
 461:              if (selected_index == -1) index = ddl.SelectedIndex;
 462:              else index = selected_index;
 463:   
 464:              ddl.Items.Clear();
 465:              //ddl.Items.Add(new ListItem("XXX","0"));
 466:              ddl.DataSource = source_dt;
 467:              ddl.DataTextField = text_field;
 468:              ddl.DataValueField = value_field;
 469:              ddl.DataBind();
 470:              ddl.SelectedIndex = index;
 471:          }
 472:  #endif
 473:          ////////////////////////////////////////////////////////////////////////////
 474:   
 475:          /// <summary>
 476:          ///
 477:          /// </summary>
 478:          public static bool IsFloat(string line)
 479:          {
 480:              // this check if line is floating point number. 
 481:              bool ni = false;
 482:   
 483:              try { float x = float.Parse(line); ni = true; }
 484:              catch (Exception) { ni = false; }
 485:   
 486:              return ni;
 487:          }
 488:   
 489:          ////////////////////////////////////////////////////////////////////////////
 490:   
 491:          /// <summary>
 492:          ///
 493:          /// </summary>
 494:          public static bool IsDecimal(string line)
 495:          {
 496:              // this check if line is a decimal number. 
 497:              bool ni = false;
 498:   
 499:              try { decimal x = decimal.Parse(line); ni = true; }
 500:              catch (Exception) { ni = false; }
 501:   
 502:              return ni;
 503:          }
 504:   
 505:          ////////////////////////////////////////////////////////////////////////////
 506:   
 507:          /// <summary>
 508:          ///
 509:          /// </summary>
 510:          public static bool IsInt(string line)
 511:          {
 512:              // this check if line is an integer
 513:              bool ni = false;
 514:   
 515:              try { int x = int.Parse(line); ni = true; }
 516:              catch (Exception) { ni = false; }
 517:   
 518:              return ni;
 519:          }
 520:   
 521:          ////////////////////////////////////////////////////////////////////////////
 522:   
 523:          /// <summary>
 524:          ///
 525:          /// </summary>
 526:          public static string ByteToHex(byte[] bytes)
 527:          {
 528:              StringBuilder sb = new StringBuilder(2500);
 529:   
 530:              UTF8Encoding utf8 = new UTF8Encoding();
 531:              foreach (byte b in bytes) sb.Append(b.ToString("x2"));
 532:   
 533:              return sb.ToString();
 534:          }
 535:   
 536:          ////////////////////////////////////////////////////////////////////////////
 537:   
 538:          /// <summary>
 539:          ///
 540:          /// </summary>
 541:          public static byte[] HexToByte(string hex_str)
 542:          {
 543:              int i, n;
 544:              byte[] bytes;
 545:              char[] chars;
 546:              string c_str = "";
 547:              UTF8Encoding utf8 = new UTF8Encoding();
 548:   
 549:              chars = hex_str.ToCharArray();
 550:   
 551:              bytes = new byte[chars.Length / 2];  // since hex_str has two chars for every byte
 552:   
 553:              n = 0;
 554:              for (i = 0; i < chars.Length; i += 2)
 555:              {
 556:                  c_str = chars[i].ToString() + chars[i + 1].ToString();
 557:                  bytes[n++] = (byte)Convert.ToInt32(c_str, 16);
 558:              }
 559:   
 560:              return bytes;
 561:          }
 562:   
 563:          ////////////////////////////////////////////////////////////////////////////
 564:   
 565:          /// <summary>
 566:          ///
 567:          /// </summary>
 568:          public static string DecToHex(int dec)
 569:          {
 570:              uint uiDecimal = 0;
 571:              string hex;
 572:   
 573:              try
 574:              {
 575:                  // convert text string to unsigned integer
 576:                  uiDecimal = checked((uint)System.Convert.ToUInt32(dec));
 577:   
 578:                  hex = String.Format("{0:x2}", uiDecimal);
 579:              }
 580:              catch (System.OverflowException)
 581:              {
 582:                  // Show overflow message and return
 583:                  hex = "";
 584:              }
 585:   
 586:              return hex;
 587:          }
 588:   
 589:          ////////////////////////////////////////////////////////////////////////////
 590:   
 591:          /// <summary>
 592:          ///
 593:          /// </summary>
 594:          public static int HexToDec(string hex)
 595:          {
 596:              // To hold our converted unsigned integer32 value
 597:              uint dec;
 598:   
 599:              try
 600:              {
 601:                  // Convert hex string to unsigned integer
 602:                  dec = System.Convert.ToUInt32(hex, 16);
 603:              }
 604:              catch (System.OverflowException)
 605:              {
 606:                  // Show overflow message and return
 607:                  return 0;
 608:              }
 609:   
 610:              return (int)dec;
 611:          }
 612:   
 613:          ////////////////////////////////////////////////////////////////////////////
 614:   
 615:          /// <summary>
 616:          /// http://stackoverflow.com/questions/3702216/how-to-convert-integer-to-binary-string-in-c
 617:          /// </summary>
 618:          public static string IntegerToBinaryString(int x)
 619:          {
 620:              return Convert.ToString(x, 2);
 621:          }
 622:   
 623:          ////////////////////////////////////////////////////////////////////////////
 624:   
 625:          /// <summary>
 626:          /// pos 0 is least significant bit, pos 7 is most
 627:          /// http://stackoverflow.com/questions/2431732/checking-if-a-bit-is-set-or-not
 628:          /// </summary>
 629:          public static bool IsBitSet(byte b, int pos)
 630:          {
 631:              return (b & (1 << pos)) != 0;
 632:          }
 633:   
 634:          ////////////////////////////////////////////////////////////////////////////
 635:   
 636:          /// <summary>
 637:          ///
 638:          /// </summary>
 639:          public static DataTable GenerateEmptyDataTable(DataTable dt)
 640:          {
 641:              // this function is used to produce a single empty DataTable line to make the GridView look nicer.
 642:              // this will simply clone the in_dt and create a completly empty line
 643:              DataRow dr;
 644:   
 645:              if (dt.Rows.Count == 0)
 646:              {
 647:   
 648:                  try
 649:                  {
 650:                      dr = dt.NewRow();
 651:   
 652:                      foreach (DataColumn dc in dt.Columns)
 653:                      {
 654:                          dr[dc.ColumnName] = DBNull.Value;
 655:                      }
 656:   
 657:                      dt.Rows.Add(dr);
 658:                  }
 659:                  catch (Exception)
 660:                  {
 661:                      return null;
 662:                  }
 663:              }
 664:   
 665:              return dt;
 666:          }
 667:   
 668:  #if WFA
 669:  #else
 670:          ////////////////////////////////////////////////////////////////////////////
 671:   
 672:          /// <summary>
 673:          /// 
 674:          /// </summary>
 675:          public static string GetPostBackControl(Page page)
 676:          {
 677:              // return the name of control that fired the postback
 678:              // this is strange, sometimes it fills the ID with real name of control and sometimes the TEXT
 679:   
 680:              string s = "";
 681:              Control c = null;
 682:   
 683:              string ctrlname = page.Request.Params.Get("__EVENTTARGET");
 684:              if (ctrlname != null && ctrlname != string.Empty)
 685:              {
 686:                  c = page.FindControl(ctrlname);
 687:              }
 688:              else
 689:              {
 690:                  foreach (string ctl in page.Request.Form)
 691:                  {
 692:                      Control ci = page.FindControl(ctl);
 693:                      if (ci is System.Web.UI.WebControls.Button)
 694:                      {
 695:                          c = ci;
 696:                          break;
 697:                      }
 698:                  }
 699:              }
 700:   
 701:              if (c != null)
 702:              {
 703:                  if (c.GetType().ToString() == "System.Web.UI.WebControls.Button")
 704:                  {
 705:                      s = ((System.Web.UI.WebControls.Button)c).ID;
 706:                  }
 707:                  else if (c.GetType().ToString() == "System.Web.UI.WebControls.DropDownList")
 708:                  {
 709:                      s = ((System.Web.UI.WebControls.DropDownList)c).ID;
 710:                  }
 711:                  else s = "";
 712:              }
 713:              else s = "";
 714:   
 715:              return s;
 716:          }
 717:   
 718:  #endif
 719:   
 720:          ////////////////////////////////////////////////////////////////////////////
 721:   
 722:          /// <summary>
 723:          ///
 724:          /// </summary>
 725:          public static string Color(int count, int index)
 726:          {
 727:              string s;
 728:   
 729:              // rainbow:
 730:              string[] color = { "#f00", "#f10", "#f20", "#f30", "#f40", "#f50", "#f60", "#f70", "#f80", "#f90", "#fa0", "#fb0", "#fc0", "#fd0", "#fe0", "#ff0", "#ef0", "#df0", "#cf0", "#bf0", "#af0", "#9f0", "#8f0", "#7f0", "#6f0", "#5f0", "#4f0", "#3f0", "#2f0", "#1f0", "#0f0", "#0f1", "#0f2", "#0f3", "#0f4", "#0f5", "#0f6", "#0f7", "#0f8", "#0f9", "#0fa", "#0fb", "#0fc", "#0fd", "#0fe", "#0ff", "#0ef", "#0df", "#0cf", "#0bf", "#0af", "#09f", "#08f", "#07f", "#06f", "#05f", "#04f", "#03f", "#02f", "#01f", "#00f", "#10f", "#20f", "#30f", "#40f", "#50f", "#60f", "#70f", "#80f", "#90f", "#a0f", "#b0f", "#c0f", "#d0f", "#e0f" };
 731:   
 732:              // random clear
 733:              //string[] color = {"Black","Blue","BlueViolet","Brown","CadetBlue","CornFlowerBlue","Crimson","DarkBlue","DarkCyan","DarkGoldenRod","DarkGreen","DarkMagenta","DarkOliveGreen","DarkOrange","DarkOrchid","DarkRed","DarkSlateBlue","DarkSlateGray","DarkViolet","Firebrick","ForestGreen","Green","IndianRed","Indigo","LightGray","LightSeaGreen","LightSkyBlue","LightSlateGray","Maroon","MediumBlue","MediumOrchid","MediumPurple","MediumSeaGreen","MediumSlateBlue","MediumVioletRed","MidnightBlue","Navy","Olive","OliveDrab"," Orange","OrangeRed","Orchid","Purple","Red","RosyBrown","RoyalBlue","SaddleBrown","SlateBlue","SlateGray","Teal","Tomato","Transparent" };
 734:   
 735:              if (index > 0) index--;
 736:   
 737:              s = color[color.Length / count * index];
 738:   
 739:              return s;
 740:          }
 741:   
 742:          ////////////////////////////////////////////////////////////////////////////
 743:   
 744:          /// <summary>
 745:          ///
 746:          /// </summary>
 747:          public static List<string> PaintColorList(int count, int index)
 748:          {
 749:              var s = new List<string>() { "000000", "7F7F7F", "880015", "ED1C24", "FF7F27", "FFF200", "22B14C", "00A2E8", "3F48CC", "A349A4", "FFFFFF", "C3C3C3", "B97A57", "FFAEC9", "FFC90E", "EFE4B0", "B5E61D", "99D9EA", "7092BE", "C8BFE7" };
 750:   
 751:              return s;
 752:          }
 753:   
 754:          ////////////////////////////////////////////////////////////////////////////
 755:   
 756:          /// <summary>
 757:          ///
 758:          /// </summary>
 759:          public static string FormatHtml(string text)
 760:          {
 761:              text = Regex.Replace(text, @"[\n|\r]+", "</p><p>");
 762:              text = "<p>" + text + "</p>";
 763:   
 764:              return text;
 765:          }
 766:   
 767:          ////////////////////////////////////////////////////////////////////////////
 768:          ////////////////////////////////////////////////////////////////////////////
 769:   
 770:          /// <summary>
 771:          ///
 772:          /// <see href="http://stackoverflow.com/questions/11412956/what-is-the-best-way-of-validating-an-ip-address"/>
 773:          /// </summary>
 774:          public static bool IsValidIpv4(string ipString)
 775:          {
 776:              bool isValid;
 777:              byte tempForParsing;
 778:              string[] splitValues;
 779:   
 780:              if (!string.IsNullOrWhiteSpace(ipString) && !string.IsNullOrEmpty(ipString))
 781:              {
 782:                  splitValues = ipString.Split('.');
 783:   
 784:                  if (splitValues.Length != 4) isValid = false;
 785:                  else
 786:                  {
 787:                      isValid = splitValues.All(r => byte.TryParse(r, out tempForParsing));
 788:                  }
 789:              }
 790:              else isValid = false;
 791:   
 792:              return isValid;
 793:          }
 794:   
 795:          ////////////////////////////////////////////////////////////////////////////
 796:   
 797:          /// <summary>
 798:          ///
 799:          /// <see href="https://stackoverflow.com/questions/7578857/how-to-check-whether-a-string-is-a-valid-http-url"/>
 800:          /// </summary>
 801:          public static bool IsValidUrl(string uriName)
 802:          {
 803:              var isValid = Uri.TryCreate(uriName, UriKind.Absolute, out Uri uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
 804:   
 805:              return isValid;
 806:          }
 807:   
 808:          ////////////////////////////////////////////////////////////////////////////
 809:   
 810:          /// <summary>
 811:          ///
 812:          /// </summary>
 813:          public static uint IpToUint(string ip)
 814:          {
 815:              uint uintAddress;
 816:   
 817:              IPAddress address = IPAddress.Parse(ip);
 818:              byte[] bytes = address.GetAddressBytes();
 819:              Array.Reverse(bytes); // flip big-endian(network order) to little-endian
 820:              uintAddress = BitConverter.ToUInt32(bytes, 0);
 821:   
 822:              return uintAddress;
 823:   
 824:              /*
 825:              string delimStr = ".";
 826:              char[] delimiter = delimStr.ToCharArray();
 827:              string[] ip_addr = null;
 828:              long ip_num = 0;
 829:  
 830:              try
 831:              {
 832:                  ip_addr = ip.Split(delimiter, 4);
 833:                  ip_num = (long.Parse(ip_addr[0]) * 16777216) + (long.Parse(ip_addr[1]) * 65536) + (long.Parse(ip_addr[2]) * 256) + (long.Parse(ip_addr[3]));
 834:              }
 835:              catch (Exception)
 836:              {
 837:              }
 838:  
 839:              return ip_num;
 840:              */
 841:   
 842:              /*
 843:              long l;
 844:              string r;
 845:              Match m;
 846:  
 847:              m = Regex.Match(ip, @"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})");
 848:  
 849:              if (m.Success)
 850:              {
 851:                  r = m.Groups[1].Captures[0].Value.PadLeft(3, '0') + m.Groups[2].Captures[0].Value.PadLeft(3, '0') + m.Groups[3].Captures[0].Value.PadLeft(3, '0') + m.Groups[4].Captures[0].Value.PadLeft(3, '0');
 852:                  l = long.Parse(r);
 853:              }
 854:              else l = 0;
 855:  
 856:              return l;
 857:              */
 858:          }
 859:   
 860:          ////////////////////////////////////////////////////////////////////////////
 861:   
 862:          /// <summary>
 863:          ///
 864:          /// </summary>
 865:          public static string UintToIp(uint ui)
 866:          {
 867:              string ipAddress;
 868:   
 869:              byte[] bytes = BitConverter.GetBytes(ui);
 870:              Array.Reverse(bytes); // flip little-endian to big-endian(network order)
 871:              ipAddress = new IPAddress(bytes).ToString();
 872:   
 873:              return ipAddress;
 874:   
 875:              /*
 876:              string s, s1, s2, s3, s4;
 877:  
 878:              s = l.ToString();
 879:              s = s.PadLeft(12, '0');
 880:  
 881:              s1 = s.Substring(0, 3);
 882:              s2 = s.Substring(3, 3);
 883:              s3 = s.Substring(6, 3);
 884:              s4 = s.Substring(9, 3);
 885:  
 886:              s = s1 + "." + s2 + "." + s3 + "." + s4;
 887:  
 888:              s = Regex.Replace(s, @"\.0+", ".");
 889:              s = Regex.Replace(s, @"^0+", "");
 890:              if (s[s.Length - 1] == '.') s = s + "0";
 891:  
 892:              return s;
 893:              */
 894:          }
 895:   
 896:          ////////////////////////////////////////////////////////////////////////////
 897:   
 898:          /// <summary>
 899:          ///
 900:          /// </summary>
 901:          public static string IpToHex(string ip)
 902:          {
 903:              string h;
 904:              Match m;
 905:   
 906:              h = "";
 907:   
 908:              m = Regex.Match(ip, @"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})");
 909:   
 910:              if (m.Success)
 911:              {
 912:                  h = DecToHex(int.Parse(m.Groups[1].Captures[0].Value)) + DecToHex(int.Parse(m.Groups[2].Captures[0].Value)) + DecToHex(int.Parse(m.Groups[3].Captures[0].Value)) + DecToHex(int.Parse(m.Groups[4].Captures[0].Value));
 913:              }
 914:              else h = "";
 915:   
 916:              return h;
 917:          }
 918:   
 919:          ////////////////////////////////////////////////////////////////////////////
 920:   
 921:          /// <summary>
 922:          ///
 923:          /// </summary>
 924:          public static string HexToIp(string h)
 925:          {
 926:              string s, s1, s2, s3, s4;
 927:   
 928:              h = h.PadLeft(8, '0');
 929:   
 930:              s1 = h.Substring(0, 2);
 931:              s2 = h.Substring(2, 2);
 932:              s3 = h.Substring(4, 2);
 933:              s4 = h.Substring(6, 2);
 934:   
 935:              s = HexToDec(s1) + "." + HexToDec(s2) + "." + HexToDec(s3) + "." + HexToDec(s4);
 936:   
 937:              return s;
 938:          }
 939:   
 940:          ////////////////////////////////////////////////////////////////////////////
 941:   
 942:          /// <summary>
 943:          ///
 944:          /// </summary>
 945:          public static string DecToIp(int i)
 946:          {
 947:              return HexToIp(DecToHex(i));
 948:          }
 949:   
 950:          ////////////////////////////////////////////////////////////////////////////
 951:   
 952:          /// <summary>
 953:          ///
 954:          /// </summary>
 955:          public static int IpToDec(string s)
 956:          {
 957:              return HexToDec(IpToHex(s));
 958:          }
 959:   
 960:          ////////////////////////////////////////////////////////////////////////////
 961:   
 962:          /// <summary>
 963:          /// Check a string to see if all characters are hexadecimal values
 964:          /// <see href="https://stackoverflow.com/questions/223832/check-a-string-to-see-if-all-characters-are-hexadecimal-values"/>
 965:          /// </summary>
 966:          public static bool IsHex(string term)
 967:          {
 968:              // For C-style hex notation (0xFF) you can use @"\A\b(0[xX])?[0-9a-fA-F]+\b\Z"
 969:              return System.Text.RegularExpressions.Regex.IsMatch(term, @"\A\b[0-9a-fA-F]+\b\Z");
 970:          }
 971:   
 972:          ////////////////////////////////////////////////////////////////////////////
 973:   
 974:          /// <summary>
 975:          ///
 976:          /// </summary>
 977:          public static string NetworkNumberFromIp(string ip)
 978:          {
 979:              string[] ipp;
 980:              string networkNumber;
 981:   
 982:              networkNumber = "";
 983:   
 984:              if (IsValidIpv4(ip))
 985:              {
 986:                  ipp = ip.Split('.');
 987:   
 988:                  networkNumber = (ipp[0] + "." + ipp[1] + "." + ipp[2] + ".0");
 989:              }
 990:   
 991:              return networkNumber;
 992:          }
 993:   
 994:          ////////////////////////////////////////////////////////////////////////////
 995:   
 996:          /// <summary>
 997:          ///
 998:          /// </summary>
 999:          public static List<string> NetworkNumberStrippedList(string startIp, string endIp)
        {
            int startIpI, endIpI;
            string s;
            List<long> li;
            List<string> list;
 
            li = new List<long>();
            list = new List<string>();
 
            // change network number to a real IP
            if (Regex.IsMatch(startIp, @"^.+\.0$")) startIp = Regex.Replace(startIp, @"^(.+)\.0$", "$1.1");
            if (Regex.IsMatch(endIp, @"^.+\.0$")) endIp = Regex.Replace(endIp, @"^(.+)\.0$", "$1.1");
 
            startIpI = IpToDec(startIp);
            endIpI = IpToDec(endIp);
 
            for (int i = startIpI; i <= endIpI; i += 256)
            {
                s = DecToIp(i);
                s = NetworkNumberFromIp(s);
 
                s = Regex.Replace(s, @"^(.+)\.0$", "$1");
 
                list.Add(s);
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Check if the passed IP address belongs to Kuwait
        /// </summary>
        public static bool IsKuwaitIp(string ip)
        {
            bool b;
            uint ui;
 
            ui = Ia.Cl.Model.Default.IpToUint(ip);
 
            if (
            (ui >= 1044742144 && ui <= 1044750335)
            || (ui >= 1050017792 && ui <= 1050083327)
            || (ui >= 1054277632 && ui <= 1054343167)
            || (ui >= 1075513152 && ui <= 1075513183)
            || (ui >= 1125110400 && ui <= 1125110463)
            || (ui >= 1161630912 && ui <= 1161630919)
            || (ui >= 1161641888 && ui <= 1161641911)
            || (ui >= 1163558016 && ui <= 1163558028)
            || (ui >= 1308094464 && ui <= 1308096511)
            || (ui >= 1314455552 && ui <= 1314521087)
            || (ui >= 1318764544 && ui <= 1318780927)
            || (ui >= 1319084032 && ui <= 1319092223)
            || (ui >= 1347219456 && ui <= 1347223551)
            || (ui >= 1347294424 && ui <= 1347294431)
            || (ui >= 1347321856 && ui <= 1347323775)
            || (ui >= 1347323904 && ui <= 1347325183)
            || (ui >= 1347325440 && ui <= 1347325951)
            || (ui >= 1354235904 && ui <= 1354301439)
            || (ui >= 1361035904 && ui <= 1361035907)
            || (ui >= 1361036764 && ui <= 1361036767)
            || (ui >= 1361036792 && ui <= 1361036795)
            || (ui >= 1365220792 && ui <= 1365220799)
            || (ui >= 1383273984 && ui <= 1383276543)
            || (ui >= 1383367168 && ui <= 1383367679)
            || (ui >= 1383368848 && ui <= 1383368895)
            || (ui >= 1383369120 && ui <= 1383369231)
            || (ui >= 1383369248 && ui <= 1383369535)
            || (ui >= 1383369600 && ui <= 1383370751)
            || (ui >= 1383371776 && ui <= 1383374591)
            || (ui >= 1385283584 && ui <= 1385291775)
            || (ui >= 1397006336 && ui <= 1397014527)
            || (ui >= 1398800384 && ui <= 1398833151)
            || (ui >= 1403658528 && ui <= 1403658559)
            || (ui >= 1410013696 && ui <= 1410013727)
            || (ui >= 1410013920 && ui <= 1410013951)
            || (ui >= 1410014016 && ui <= 1410014047)
            || (ui >= 1410014464 && ui <= 1410014495)
            || (ui >= 1410027008 && ui <= 1410027263)
            || (ui >= 1410035200 && ui <= 1410035231)
            || (ui >= 1410035264 && ui <= 1410035295)
            || (ui >= 1425426432 && ui <= 1425428479)
            || (ui >= 1441726464 && ui <= 1441729023)
            || (ui >= 1441729536 && ui <= 1441734655)
            || (ui >= 1475115008 && ui <= 1475117055)
            || (ui >= 1500186624 && ui <= 1500188671)
            || (ui >= 1506476032 && ui <= 1506508799)
            || (ui >= 1509642240 && ui <= 1509644351)
            || (ui >= 1509644384 && ui <= 1509646335)
            || (ui >= 1533419520 && ui <= 1533419775)
            || (ui >= 1533420032 && ui <= 1533420287)
            || (ui >= 1533420544 && ui <= 1533421567)
            || (ui >= 1533448192 && ui <= 1533450239)
            || (ui >= 1533470720 && ui <= 1533472767)
            || (ui >= 1533513728 && ui <= 1533515775)
            || (ui >= 1535934464 && ui <= 1535967231)
            || (ui >= 1536660016 && ui <= 1536660019)
            || (ui >= 1536663424 && ui <= 1536663551)
            || (ui >= 1539227648 && ui <= 1539229695)
            || (ui >= 1539466752 && ui <= 1539467263)
            || (ui >= 1539473920 && ui <= 1539474431)
            || (ui >= 1539737088 && ui <= 1539737343)
            || (ui >= 1540410112 && ui <= 1540410367)
            || (ui >= 1540467712 && ui <= 1540467967)
            || (ui >= 1540622336 && ui <= 1540622591)
            || (ui >= 1540628480 && ui <= 1540628735)
            || (ui >= 1540790272 && ui <= 1540791295)
            || (ui >= 1572814848 && ui <= 1572816895)
            || (ui >= 1578991616 && ui <= 1579024383)
            || (ui >= 1585446912 && ui <= 1585577983)
            || (ui >= 1589346304 && ui <= 1589379071)
            || (ui >= 1598160896 && ui <= 1598193663)
            || (ui >= 1603137536 && ui <= 1603141631)
            || (ui >= 1605320704 && ui <= 1605328895)
            || (ui >= 1925638656 && ui <= 1925638911)
            || (ui >= 1925639680 && ui <= 1925639935)
            || (ui >= 2341273600 && ui <= 2341339135)
            || (ui >= 2717646848 && ui <= 2717712383)
            || (ui >= 2830827520 && ui <= 2830893055)
            || (ui >= 3169255424 && ui <= 3169271807)
            || (ui >= 3169275904 && ui <= 3169278991)
            || (ui >= 3169279008 && ui <= 3169279231)
            || (ui >= 3169279256 && ui <= 3169279263)
            || (ui >= 3169279296 && ui <= 3169279303)
            || (ui >= 3169279320 && ui <= 3169279743)
            || (ui >= 3169279760 && ui <= 3169281023)
            || (ui >= 3169281280 && ui <= 3169288191)
            || (ui >= 3239285760 && ui <= 3239286783)
            || (ui >= 3239488512 && ui <= 3239488767)
            || (ui >= 3240222720 && ui <= 3240223231)
            || (ui >= 3240812288 && ui <= 3240812543)
            || (ui >= 3245088256 && ui <= 3245088511)
            || (ui >= 3249111552 && ui <= 3249112063)
            || (ui >= 3250335744 && ui <= 3250339839)
            || (ui >= 3250359808 && ui <= 3250362879)
            || (ui >= 3250364416 && ui <= 3250372607)
            || (ui >= 3251120128 && ui <= 3251120639)
            || (ui >= 3252483072 && ui <= 3252483583)
            || (ui >= 3252484096 && ui <= 3252486143)
            || (ui >= 3258368000 && ui <= 3258384383)
            || (ui >= 3262477220 && ui <= 3262477223)
            || (ui >= 3262478601 && ui <= 3262478601)
            || (ui >= 3263045632 && ui <= 3263046847)
            || (ui >= 3263046912 && ui <= 3263047935)
            || (ui >= 3263048192 && ui <= 3263053823)
            || (ui >= 3266341888 && ui <= 3266342143)
            || (ui >= 3274145792 && ui <= 3274162175)
            || (ui >= 3276114944 && ui <= 3276115967)
            || (ui >= 3276687872 && ui <= 3276688383)
            || (ui >= 3276858112 && ui <= 3276858367)
            || (ui >= 3277381120 && ui <= 3277381631)
            || (ui >= 3280580096 && ui <= 3280580351)
            || (ui >= 3285922816 && ui <= 3285923327)
            || (ui >= 3286425600 && ui <= 3286433791)
            || (ui >= 3286566656 && ui <= 3286567423)
            || (ui >= 3286568192 && ui <= 3286568703)
            || (ui >= 3286571008 && ui <= 3286571775)
            || (ui >= 3288417536 && ui <= 3288418047)
            || (ui >= 3340584704 && ui <= 3340584959)
            || (ui >= 3350042880 && ui <= 3350043135)
            || (ui >= 3453376848 && ui <= 3453376887)
            || (ui >= 3487969792 && ui <= 3487970047)
            || (ui >= 3509522432 && ui <= 3509522687)
            || (ui >= 3509559040 && ui <= 3509559295)
            || (ui >= 3512891232 && ui <= 3512891263)
            || (ui >= 3517438880 && ui <= 3517438911)
            || (ui >= 3518894096 && ui <= 3518894103)
            || (ui >= 3523593216 && ui <= 3523593231)
            || (ui >= 3559587840 && ui <= 3559596031)
            || (ui >= 3561742336 && ui <= 3561750527)
            || (ui >= 3575824384 && ui <= 3575832575)
            || (ui >= 3582255104 && ui <= 3582263295)
            || (ui >= 3585949696 && ui <= 3585957887)
            || (ui >= 3628153088 && ui <= 3628153343)
            || (ui >= 3630097664 && ui <= 3630098175)
            || (ui >= 3630100224 && ui <= 3630100479)
            || (ui >= 3632481760 && ui <= 3632481767)
            || (ui >= 3645222912 && ui <= 3645227007)
            ) b = true;
            else b = false;
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static bool IsPrivateIp(string userHostAddress)
        {
            bool isPrivate;
            int[] ipParts;
 
            ipParts = userHostAddress.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries).Select(s => int.Parse(s)).ToArray();
 
            if (ipParts[0] == 10 || (ipParts[0] == 192 && ipParts[1] == 168) || (ipParts[0] == 172 && (ipParts[1] >= 16 && ipParts[1] <= 31)))
            {
                isPrivate = true;
            }
            else
            {
                // IP address is probably public. This doesn't catch some VPN ranges like OpenVPN and Hamachi.
                isPrivate = false;
            }
 
            return isPrivate;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Check if the this.Request.UserHostAddress from the webpage is from the development machine or IP.
        /// <param name="userHostAddress">The this.Request.UserHostAddress from the webpage</param>
        /// </summary>
        public static bool IsIaHostAddress(string userHostAddress)
        {
            bool b;
            string hostAddress;
 
            if (ConfigurationManager.AppSettings["iaHostAddress"] != null)
            {
                hostAddress = ConfigurationManager.AppSettings["iaHostAddress"].ToString();
 
                if (userHostAddress == hostAddress || userHostAddress == "::1") b = true;
                else b = false;
            }
            else b = false;
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static bool IsNgnOfficeHostAddress(string userHostAddress)
        {
            bool b;
            string hostAddress;
 
            if (ConfigurationManager.AppSettings["ngnOfficeHostAddress"] != null)
            {
                hostAddress = ConfigurationManager.AppSettings["ngnOfficeHostAddress"].ToString();
 
                if (userHostAddress == hostAddress || userHostAddress == "::1") b = true;
                else b = false;
            }
            else
            {
                b = userHostAddress.Contains("91.140."); // Ministry Liberation Tower 3rd floor
            }
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string RequestUserIP()
        {
            string ip, ipList;
 
            ipList = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
 
            if (!string.IsNullOrEmpty(ipList))
            {
                ip = ipList.Split(',')[0];
            }
            else ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
 
            return ip;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Hashtable DataTableToHashtable(DataTable dt)
        {
            // put the datatable first row value into a hashtable key, and second as value. if the table has only one column we will add it only to keys with 0 value
            Hashtable ht;
 
            if (dt != null)
            {
                if (dt.Rows.Count > 0)
                {
 
                    ht = new Hashtable(dt.Rows.Count);
 
                    if (dt.Columns.Count == 1) foreach (DataRow r in dt.Rows) ht[r[0].ToString()] = "0";
                    else if (dt.Columns.Count > 1) foreach (DataRow r in dt.Rows) ht[r[0].ToString()] = r[1].ToString();
                }
                else ht = new Hashtable(1);
            }
            else ht = null;
 
            return ht;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string DataTableToString(DataTable dataTable)
        {
            var output = new StringBuilder();
 
            // write Column titles
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                var text = dataTable.Columns[i].ColumnName;
                output.Append("\t" + text);
            }
 
            output.Append("|\n" + new string('=', output.Length) + "\n");
 
            // write rows
            foreach (DataRow row in dataTable.Rows)
            {
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    var text = row[i].ToString();
                    output.Append("\t" + text);
                }
 
                output.Append("|\n");
            }
 
            return output.ToString();
        }
 
        /*
        ////////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///
        /// </summary>
        public static ArrayList ArrayList_Limit_Randomize(ArrayList in_al, int max)
        {
            // 
            // parameter: ArrayList with any number of entries, an integer value indicating the max possible number of returned values
            // procedure: randomly select upto max values from al and return max >= num >= 0
            int n, o;
            ArrayList al;
            Hashtable ht;
            if (max > 0)
            {
                al = new ArrayList(max);
                ht = new Hashtable(max);
                o = 0;
                while (o < in_al.Count - 1 && o < max)
                {
                    foreach (string s in in_al)
                    {
                        n = r.Next(max);
                        if (!ht.ContainsKey(n))
                        {
                            al.Add(s);
                            ht[n] = 1;
                            o++;
                        }
                    }
                }
            }
            else al = null;
            return al;
        }
        */
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList SublistArrayList(ArrayList in_al, int n)
        {
            // return the first n values from all
            ArrayList al;
 
            if (n > 0)
            {
                al = new ArrayList(n);
 
                for (int i = 0; i < in_al.Count - 1 && i < n; i++)
                {
                    al.Add(in_al[i]);
                }
            }
            else al = null;
 
            return al;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList ShuffleAndSublistArrayList(ArrayList in_al, int n)
        {
            // 
 
            ShuffleArrayList(in_al);
 
            return SublistArrayList(in_al, n);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList KeyArrayHashtableToList(Hashtable ht)
        {
            // 
            ArrayList al;
 
            if (ht != null)
            {
                if (ht.Count > 0)
                {
                    al = new ArrayList(ht.Count);
 
                    foreach (string s in ht.Keys) al.Add(s);
                }
                else al = new ArrayList(1);
            }
            else al = null;
 
            al.Sort();
 
            return al;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList KeyIntegerHashtableToArrayList(Hashtable ht)
        {
            // 
            ArrayList al;
 
            if (ht != null)
            {
                if (ht.Count > 0)
                {
                    al = new ArrayList(ht.Count);
 
                    foreach (int i in ht.Keys) al.Add(i);
                }
                else al = new ArrayList(1);
            }
            else al = null;
 
            al.Sort();
 
            return al;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Hashtable ReverseKeyValueInHashtable(Hashtable in_ht)
        {
            // 
            Hashtable ht;
 
            if (in_ht != null)
            {
                if (in_ht.Count > 0)
                {
                    ht = new Hashtable(in_ht.Count);
 
                    foreach (string s in in_ht.Keys) ht[in_ht[s].ToString()] = s;
                }
                else ht = new Hashtable(1);
            }
            else ht = null;
 
            return ht;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList HashtableValueToArrayList(Hashtable ht)
        {
            // 
            ArrayList al;
 
            if (ht != null)
            {
                if (ht.Count > 0)
                {
                    al = new ArrayList(ht.Count);
 
                    foreach (string s in ht.Values) al.Add(s);
                }
                else al = new ArrayList(1);
            }
            else al = null;
 
            al.Sort();
 
            return al;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string HashtableKeyString(Hashtable ht)
        {
            // 
            string si;
            StringBuilder sb;
 
            if (ht != null)
            {
                if (ht.Count > 0)
                {
                    sb = new StringBuilder(ht.Count);
                    sb.Length = 0;
 
                    foreach (string s in ht.Keys) sb.Append(s + "|");
                }
                else sb = new StringBuilder(1);
            }
            else sb = null;
 
            si = sb.ToString();
            si = si.Remove(si.Length - 1, 1);
 
            return si;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Hashtable SortHashtableKey(Hashtable in_ht)
        {
            // sort the hashtable keys alphabetically
 
            ArrayList al;
            Hashtable ht;
 
            if (in_ht != null)
            {
                if (in_ht.Count > 0)
                {
                    al = new ArrayList(in_ht.Count + 1);
                    ht = new Hashtable(in_ht.Count + 1);
 
                    al.Clear();
                    foreach (string s in in_ht.Keys) al.Add(s);
                    al.Sort();
                    foreach (string s in al) ht.Add(s, in_ht[s].ToString());
                }
                else ht = in_ht;
            }
            else ht = in_ht;
 
            return ht;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string HashtableValueString(Hashtable ht)
        {
            // 
            string si;
            StringBuilder sb;
 
            if (ht != null)
            {
                if (ht.Count > 0)
                {
                    sb = new StringBuilder(ht.Count);
                    sb.Length = 0;
 
                    foreach (string s in ht.Keys) sb.Append(ht[s].ToString() + "|");
                }
                else sb = new StringBuilder(1);
            }
            else sb = null;
 
            si = sb.ToString();
            si = si.Remove(si.Length - 1, 1);
 
            return si;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static string Match(string text, string regex)
        {
            string matchedText;
            Match m;
 
            m = Regex.Match(text, regex);
 
            if (m.Groups[1].Success) matchedText = m.Groups[1].Captures[0].Value;
            else matchedText = null;
 
            return matchedText;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static string MatchToLower(string s, string regex)
        {
            string t;
            Match m;
 
            m = Regex.Match(s, regex);
            if (m.Groups[1].Success) t = m.Groups[1].Captures[0].Value.ToLower();
            else t = null;
 
            return t;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static bool IsRegexPatternValid(string pattern)
        {
            bool b;
 
            try
            {
                new Regex(pattern);
 
                b = true;
            }
            catch
            {
                b = false;
            }
 
            return b;
        }
 
#if WFA
#else
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Store the current time in a cache variable
        /// </summary>
        public static void SetTimeSpan()
        {
            HttpRuntime httpRT = new HttpRuntime();
            Cache cache = HttpRuntime.Cache;
 
            cache["TimeSpan_Set"] = DateTime.UtcNow.AddHours(3).Ticks;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Check if sec seconds had passed since timespan_set
        /// </summary>
        public static bool CheckTimeSpan(int sec)
        {
            bool b;
            long l;
            HttpRuntime httpRT = new HttpRuntime();
            Cache cache = HttpRuntime.Cache;
 
            if (cache["TimeSpan_Set"] == null) b = true;
            else
            {
                l = (long)cache["TimeSpan_Set"];
 
                if (DateTime.UtcNow.AddHours(3).AddSeconds(-sec).Ticks > l) b = true;
                else b = false;
            }
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Check if 1 sec seconds had passed since timespan_set
        /// </summary>
        public static bool CheckTimeSpan()
        {
            return CheckTimeSpan(1);
        }
 
#endif
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the absolute path
        /// </summary>
        public static string AbsolutePath()
        {
            return AbsolutePath(false);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the absolute path to temp folder
        /// </summary>
        public static string AbsoluteTempPath()
        {
            return AbsolutePath(true);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the absolute path
        /// </summary>
        public static string AbsolutePath(bool temp_folder)
        {
            string path;
 
#if WFA
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed) path = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory + @"\";
            else path = AppDomain.CurrentDomain.BaseDirectory;
#else
            if (temp_folder) path = AppDomain.CurrentDomain.BaseDirectory.ToString() + @"app_data\temp\";
            else path = AppDomain.CurrentDomain.BaseDirectory.ToString();
#endif
 
            //if (path.IndexOf(@"\bin") >= 0) path = path.Remove(path.IndexOf(@"\bin"), path.Length - path.IndexOf(@"\bin"));
 
            return path;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the absolute path parent directory
        /// </summary>
        public static string AbsolutePathParent()
        {
            string s;
 
            s = AbsolutePath(false);
 
            s = s.Remove(s.Length - 1, 1);
 
            s = s.Substring(0, s.LastIndexOf(@"\")) + @"\";
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return domain name from page Uri
        /// </summary>
        public static string BasicHost(Uri uri)
        {
            string url, domain, puny, tld;
 
            url = uri.Host;
            url = url.ToLower();
 
            if (uri.Host == "localhost")
            {
                url = uri.Segments[1].Replace("/", "");
                url = url.ToLower();
                url = url.Replace("http://", "");
                url = url.Replace("https://", "");
                url = url.Replace("www.", "");
                url = url.Replace("m.", "");
            }
 
            if (url.Contains("xn--"))
            {
                // URL is punycode
                if (url.Contains(".com")) tld = "com";
                else if (url.Contains(".net")) tld = "net";
                else if (url.Contains(".org")) tld = "org";
                else tld = "?";
 
                url = url.Replace(".com", "");
                url = url.Replace(".net", "");
                url = url.Replace(".org", "");
 
                domain = Ia.Cl.Model.Punycode.Decode(url) + "." + tld;
                puny = url + "." + tld;
            }
            else
            {
                // URL is not punycode
                domain = url;
                puny = url;
            }
 
            return domain;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the absolute URL
        /// </summary>
        public static string AbsoluteUrl(Page p)
        {
            string url;
            Uri uri;
 
            uri = p.Request.Url;
 
            if (uri.Host == "localhost")
            {
                url = uri.Authority; // +@"/" + uri.Segments[1].Replace("/", "");
                url = url.ToLower();
                url = url.Replace("http://", "");
                url = url.Replace("www.", "");
            }
            else
            {
                url = uri.Host;
                url = url.ToLower();
                url = url.Replace("http://", "");
                url = url.Replace("www.", "");
            }
 
            return url;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the URL of a file from the path
        /// </summary>
        public static string AbsolutePathUrl(Page page, string file)
        {
            string s, absoluteUrl, absolutePath;
 
            absoluteUrl = AbsoluteUrl(page) + "/";
            absolutePath = AbsolutePath();
 
            s = file.Replace(absolutePath, absoluteUrl);
 
            s = s.Replace(@"\", @"/");
 
            return page.ResolveClientUrl("~/" + s);
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Shows a client-side JavaScript alert in the browser.
        /// </summary>
        public static void JavasciptSrc(Page p, string relative_url_file)
        {
            // cleans the message to allow single quotation marks
            string script;
 
            relative_url_file = relative_url_file.Replace("'", "\\'");
 
            script = "<script type=\"text/javascript\" src=\"" + Ia.Cl.Model.Default.AbsoluteUrl(p) + @"/" + relative_url_file + "\"/>";
 
            // gets the executing web page
            Page page = HttpContext.Current.CurrentHandler as Page;
 
            // checks if the handler is a Page and that the script isn't allready on the Page
            if (page != null && !page.ClientScript.IsClientScriptBlockRegistered("alert"))
            {
                page.ClientScript.RegisterClientScriptBlock(typeof(string), "alert", script);
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Make line in proper title case
        /// </summary>
        public static string ToTitleCase(string line)
        {
            TextInfo textInfo;
            List<string> notToCapitalize = new List<string>(new string[] { "a", "an", "the", "at", "by", "for", "in", "of", "on", "to", "up", "and", "as", "but", "or", "nor" });
 
            textInfo = new CultureInfo("en-US", false).TextInfo;
 
            if (line != null)
            {
                // changes a string to titlecase.
                line = textInfo.ToTitleCase(line.ToLower());
 
                // Rules for Capitalization in Titles of Articles
                // http://grammar.yourdictionary.com/capitalization/rules-for-capitalization-in-titles.html#S9rKxG2G8gp88qcx.99http://grammar.yourdictionary.com/capitalization/rules-for-capitalization-in-titles.html
 
                // "Capitalize all words in titles of publications and documents, except a, an, the, at, by, for, in, of, on, to, up, and, as, but, or, and nor.
                foreach (string s in notToCapitalize)
                {
                    line = Regex.Replace(line, "\\b" + s + "\\b", s.ToLower(), RegexOptions.IgnoreCase);
                }
            }
 
            return line;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Make the first letter of a word an upper letter
        /// </summary>
        public static string FirstLetterToUpper(string s)
        {
            string u;
 
            u = s.Substring(0, 1);
            return u.ToUpper() + s.Remove(0, 1);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Make the first letter of all words an upper letter and remove underscores
        /// </summary>
        public static string FirstWordLetterToUpperAndRemoveUnderscore(string line)
        {
            string u, v;
 
            v = "";
 
            line = RemoveUnderscore(line);
 
            foreach (string s in line.Split(' '))
            {
                u = s.Substring(0, 1);
                v += u.ToUpper() + s.Remove(0, 1) + " ";
            }
 
            if (v.Length > 0) v = v.Remove(v.Length - 1, 1);
 
            return v;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the string to Pascal case.
        /// </summary>
        /// <remarks>http://csharphelper.com/blog/2014/10/convert-between-pascal-case-camel-case-and-proper-case-in-c/</remarks>
        public static string ToPascalCase(this string s)
        {
            // If there are 0 or 1 characters, just return the string.
            if (s == null) return s;
            if (s.Length < 2) return s.ToUpper();
 
            // Split the string into words.
            string[] words = s.Split(
                new char[] { },
                StringSplitOptions.RemoveEmptyEntries);
 
            // Combine the words.
            string result = "";
            foreach (string word in words)
            {
                result +=
                    word.Substring(0, 1).ToUpper() +
                    word.Substring(1);
            }
 
            return result;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the string to camel case.
        /// </summary>
        /// <remarks>http://csharphelper.com/blog/2014/10/convert-between-pascal-case-camel-case-and-proper-case-in-c/</remarks>
        public static string ProperToCamelCase(this string s)
        {
            // If there are 0 or 1 characters, just return the string.
            if (s == null || s.Length < 2)
                return s;
 
            // Split the string into words.
            string[] words = s.Split(
                new char[] { },
                StringSplitOptions.RemoveEmptyEntries);
 
            // Combine the words.
            string result = words[0].ToLower();
            for (int i = 1; i < words.Length; i++)
            {
                result +=
                    words[i].Substring(0, 1).ToUpper() +
                    words[i].Substring(1);
            }
 
            return result;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Capitalize the first character and add a space before each capitalized letter (except the first character).
        /// </summary>
        /// <remarks>http://csharphelper.com/blog/2014/10/convert-between-pascal-case-camel-case-and-proper-case-in-c/</remarks>
        public static string CamelToProperCase(this string s)
        {
            // If there are 0 or 1 characters, just return the string.
            if (s == null) return s;
            if (s.Length < 2) return s.ToUpper();
 
            // Start with the first character.
            string result = s.Substring(0, 1).ToUpper();
 
            // Add the remaining characters.
            for (int i = 1; i < s.Length; i++)
            {
                if (char.IsUpper(s[i])) result += " ";
                result += s[i];
            }
 
            return result;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert caps delimited to underscore, lower case string
        /// </summary>
        /// <remarks>http://stackoverflow.com/questions/5796383/insert-spaces-between-words-on-a-camel-cased-token</remarks>
        public static string CapsDelimitedToUnderscoreLowercase(this string s)
        {
            string u;
 
            u = Regex.Replace(s, "(\\B[A-Z])", "_$1");
 
            return u.ToLower();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Remove underscores
        /// </summary>
        public static string RemoveUnderscore(string line)
        {
            string u;
 
            u = line.Replace('_', ' ');
 
            return u;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Regex that defines email
        /// </summary>
        public static string EmailRegex()
        {
            // http://www.regular-expressions.info/email.html
            string s;
 
            s = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b";
 
            // Text="Invalid e-mail" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" runat="server" />
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static bool IsEmail(string s)
        {
            // return true if argument is an email
            bool b;
 
            b = false;
 
            if (Regex.IsMatch(s, Ia.Cl.Model.Default.EmailRegex(), RegexOptions.IgnoreCase)) b = true;
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string Decimal(double d, int dec)
        {
            // 
            string s;
 
            if (dec == 3) s = string.Format("{0:0.000}", d);
            else if (dec == 2) s = string.Format("{0:0.00}", d);
            else if (dec == 1) s = string.Format("{0:0.0}", d);
            else s = d.ToString();
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Reverse a string
        /// </summary>
        public static string ReverseString(string t)
        {
            string s;
 
            s = "";
 
            foreach (char c in t.ToCharArray()) s = c + " " + s;
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convent the data content of a DataSet to an XmlDocument object for use in API Services.
        /// <param name="ds">DataSet to convert to XmlDocument</param>
        /// <returns>XmlDocument</returns>
        /// </summary>
 
        public static XmlDocument DataSetToXmlDocument(DataSet ds)
        {
            return DataSetToXmlDocument(ds, null);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convent the data content of a DataSet to an XmlDocument object for use in API Services.
        /// </summary>
        public static XmlDocument DataSetToXmlDocument(DataSet ds, string item_name)
        {
            XmlText xt;
            XmlElement set_xe, table_xe, row_xe, xe;
            XmlDeclaration xde;
            XmlDocument xd;
 
            xd = new XmlDocument();
 
            if (ds != null)
            {
                xde = xd.CreateXmlDeclaration("1.0", "utf-8", null);
 
                // create root element
                if (ds.DataSetName.Length > 0) set_xe = xd.CreateElement(ds.DataSetName);
                else set_xe = xd.CreateElement("set");
 
                xd.InsertBefore(xde, xd.DocumentElement);
                xd.AppendChild(set_xe);
 
                if (ds.Tables.Count > 0)
                {
                    foreach (DataTable dt in ds.Tables)
                    {
                        // create table element
                        if (dt.TableName.Length > 0) table_xe = xd.CreateElement(dt.TableName);
                        else table_xe = xd.CreateElement("table");
 
                        set_xe.AppendChild(table_xe);
 
                        if (dt.Rows.Count > 0)
                        {
                            foreach (DataRow r in dt.Rows)
                            {
                                // create a new row and add it to the root node
                                if (item_name == null) item_name = "row";
                                row_xe = xd.CreateElement(item_name);
 
                                table_xe.AppendChild(row_xe);
 
                                foreach (DataColumn dc in dt.Columns)
                                {
                                    xe = xd.CreateElement(dc.ColumnName);
 
                                    xt = xd.CreateTextNode(r[dc.ColumnName].ToString());
 
                                    xe.AppendChild(xt);
 
                                    row_xe.AppendChild(xe);
                                }
                            }
                        }
                    }
                }
                else
                {
                }
            }
            else
            {
            }
 
            return xd;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the data content of a DataTable to an XmlDocument object for use in API Services.
        /// <param name="dt">DataTable to convert to XmlDocument</param>
        /// <returns>XmlDocument</returns>
        /// </summary>
 
        public static XmlDocument DataTableToXmlDocument(DataTable dt)
        {
            return DataTableToXmlDocument(dt, null);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the data content of a DataTable to an XmlDocument object for use in API Services.
        /// </summary>
        public static XmlDocument DataTableToXmlDocument(DataTable dt, string itemName)
        {
            XmlText xt;
            XmlElement table_xe, row_xe, xe;
            XmlDeclaration xde;
            XmlDocument xd;
 
            xd = new XmlDocument();
 
            if (dt != null)
            {
                xde = xd.CreateXmlDeclaration("1.0", "utf-8", null);
 
                // create root element
                if (dt.TableName.Length > 0) table_xe = xd.CreateElement(dt.TableName);
                else table_xe = xd.CreateElement("table");
 
                xd.InsertBefore(xde, xd.DocumentElement);
                xd.AppendChild(table_xe);
 
                if (dt.Rows.Count > 0)
                {
                    foreach (DataRow r in dt.Rows)
                    {
                        // create a new row and add it to the root node
                        if (itemName == null) itemName = "row";
                        row_xe = xd.CreateElement(itemName);
 
                        table_xe.AppendChild(row_xe);
 
                        foreach (DataColumn dc in dt.Columns)
                        {
                            xe = xd.CreateElement(dc.ColumnName);
 
                            xt = xd.CreateTextNode(r[dc.ColumnName].ToString());
 
                            xe.AppendChild(xt);
 
                            row_xe.AppendChild(xe);
                        }
                    }
                }
            }
            else
            {
            }
 
            return xd;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the data content of a DataTable to an XDocument object
        /// <param name="dt">DataTable to convert to XDocument</param>
        /// <returns>XDocument</returns>
        /// </summary>
 
        public static XDocument DataTableToXDocument(DataTable dt)
        {
            return DataTableToXDocument(dt, null);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert the data content of a DataTable to an XDocument object.
        /// </summary>
        public static XDocument DataTableToXDocument(DataTable dt, string itemName)
        {
            XElement tableXElement, rowXElement, xe;
            XDeclaration xde;
            XDocument xd;
 
            if (dt != null)
            {
                xde = new XDeclaration("1.0", "utf-8", null);
 
                // create root element
                if (dt.TableName.Length > 0) tableXElement = new XElement(dt.TableName);
                else tableXElement = new XElement("table");
 
                if (dt.Rows.Count > 0)
                {
                    foreach (DataRow r in dt.Rows)
                    {
                        // create a new row and add it to the root node
                        if (itemName == null) itemName = "row";
                        rowXElement = new XElement(itemName, "");
 
                        tableXElement.Add(rowXElement);
 
                        foreach (DataColumn dc in dt.Columns)
                        {
                            xe = new XElement(dc.ColumnName, r[dc.ColumnName].ToString());
 
                            rowXElement.Add(xe);
                        }
                    }
                }
 
                xd = new XDocument(xde, tableXElement);
            }
            else
            {
                xd = null;
            }
 
            return xd;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Takes an XmlNodeList with text and value, and change them into a DataTable usable for databinding with controls
        /// </summary>
        public static DataTable XmlNodeListToDataTable(XmlNodeList xnl, string value, string text)
        {
            DataTable dt;
            DataRow dr;
 
            dt = new DataTable();
            dt.Columns.Add(value);
 
            if (value != text) dt.Columns.Add(text);
 
            foreach (XmlNode n in xnl)
            {
                dr = dt.NewRow();
                dr[value] = n.Attributes[value].Value;
                if (value != text) dr[text] = n.Attributes[text].Value;
                dt.Rows.Add(dr);
            }
 
            return dt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Takes an XmlNodeList with text and value, and change them into a DataTable usable for databinding with controls
        /// </summary>
        public static DataTable XmlNodeListToDataTable(XmlNodeList xnl, string id, string text, string url)
        {
            DataTable dt;
            DataRow dr;
 
            dt = new DataTable();
            dt.Columns.Add(id);
            dt.Columns.Add(text);
            dt.Columns.Add(url);
 
            foreach (XmlNode n in xnl)
            {
                dr = dt.NewRow();
                dr[id] = n.Attributes[id].Value;
                dr[text] = n.Attributes[text].Value;
                dr[url] = n.Attributes[url].Value;
                dt.Rows.Add(dr);
            }
 
            return dt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Takes an XmlNodeList with text and value, and extra initial entries, and change them into a DataTable usable for databinding with controls
        /// </summary>
        public static DataTable XmlNodeListToDataTable(XmlNodeList xnl, string value, string text, string init_value, string init_text)
        {
            DataTable dt;
            DataRow dr;
 
            dt = new DataTable();
            dt.Columns.Add(value);
            dt.Columns.Add(text);
 
            dr = dt.NewRow();
            dr[value] = init_value;
            dr[text] = init_text;
            dt.Rows.Add(dr);
 
            foreach (XmlNode n in xnl)
            {
                dr = dt.NewRow();
                dr[value] = n.Attributes[value].Value;
                dr[text] = n.Attributes[text].Value;
                dt.Rows.Add(dr);
            }
 
            return dt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Convert XmlDocument to a tab indented simple text format suitable for simple text and emails
        /// </summary>
        /// <remarks>http://stackoverflow.com/questions/10980237/xml-to-text-convert</remarks>
        public static string XmlDocumentToTabIndentedText(XmlDocument xmlDocument)
        {
            string s, name, text;
            StringBuilder stringBuilder = new StringBuilder();
 
            stringBuilder.AppendLine("===================");
 
            name = CamelToProperCase(xmlDocument.DocumentElement.Name);
 
            stringBuilder.AppendLine(name);
 
            s = XmlDocumentToTabIndentedTextIterator(xmlDocument.DocumentElement, out text);
 
            stringBuilder.AppendLine(s);
 
            stringBuilder.AppendLine("===================");
 
            return stringBuilder.ToString();
        }
 
        private static string XmlDocumentToTabIndentedTextIterator(XmlNode xmlNode, out string text)
        {
            string s, name;
            StringBuilder stringBuilder = new StringBuilder();
 
            text = string.Empty;
 
            if (xmlNode.NodeType == XmlNodeType.Element)
            {
                foreach (XmlNode node in xmlNode.ChildNodes)
                {
                    s = XmlDocumentToTabIndentedTextIterator(node, out text);
 
                    name = CamelToProperCase(node.Name);
 
                    if (!string.IsNullOrEmpty(text))
                    {
                        stringBuilder.AppendLine("\t" + name + ": " + text);
                    }
                    else stringBuilder.AppendLine("\t" + name);
                }
            }
            else if (xmlNode.NodeType == XmlNodeType.Text)
            {
                text = xmlNode.InnerText.Trim();
            }
            else
            {
 
            }
 
            return stringBuilder.ToString().TrimEnd();
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
#if WFA
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Return the MAC Address of the computer
        /// </summary>
        public static string Get_MAC_Address()
        {
            // This will support IPv4 and IPv6.
 
            string mac_address;
            System.Net.NetworkInformation.NetworkInterface[] nics;
 
            nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
 
            mac_address = string.Empty;
 
            foreach (System.Net.NetworkInformation.NetworkInterface adapter in nics)
            {
                if (mac_address == string.Empty)// only return MAC Address from first card  
                {
                    System.Net.NetworkInformation.IPInterfaceProperties properties = adapter.GetIPProperties();
 
                    mac_address = adapter.GetPhysicalAddress().ToString();
                }
            }
 
            return mac_address;
        }
#endif
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Download file
        /// </summary>
        public static bool DownloadFile(string url, string fileName)
        {
            // 
            bool b;
 
            try
            {
                using (System.Net.WebClient wc = new System.Net.WebClient())
                {
                    wc.DownloadFile(url, fileName);
                }
 
                b = true;
            }
            catch (Exception)
            {
                b = false;
            }
 
            return b;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Regular Expression Guid Match
        /// </summary>
        /// <remarks> 
        /// http://www.geekzilla.co.uk/view8AD536EF-BC0D-427F-9F15-3A1BC663848E.htm
        /// </remarks>
        public static bool IsGuid(string s)
        {
            bool b = false;
 
            if (!string.IsNullOrEmpty(s))
            {
                Regex r = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
 
                b = r.IsMatch(s);
            }
 
            return b;
        }
 
#if !WINDOWS_FORM
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Checks the API Service State
        /// </summary>
        public static string ApiServiceState(System.Web.HttpApplicationState has, string name, TimeSpan ts)
        {
            bool b;
            string s;
            DateTime dti;
 
            b = false;
            s = "";
 
            // check if timespan variable is stored and is not null
            if (has[name] != null && has[name + "_ts"] != null)
            {
                // check if the timespan is cleared since stored value
 
                s = has[name].ToString();
                dti = DateTime.Parse(has[name + "_ts"].ToString());
 
                if (DateTime.UtcNow.AddHours(3) > dti + ts)
                {
                    // update API Service 
                    b = true;
                }
                else
                {
                    // do nothing
                    b = false;
                }
            }
            else b = true;
 
            if (b)
            {
                // update API Service values
                /*
                Ia.Ngn.kw.com.i.Ws_Default svc = new Ia.Ngn.kw.com.i.Ws_Default();
                svc.Timeout = 5000;
                try
                {
                    s = svc.Echo("Hello!");
                }
                catch (Exception)
                {
                    s = null;
                }
                finally
                {
                    has[name] = s;
                    has[name + "_ts"] = DateTime.UtcNow.AddHours(3).ToString("yyyy-MM-dd hh:mm:ss");
                }
                */
            }
 
            return has[name].ToString() + ":" + has[name + "_ts"].ToString();
        }
#endif
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// C# to convert a string to a byte array.
        /// </summary>
        private static byte[] ConvertStringToByteArray(string str)
        {
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            return encoding.GetBytes(str);
 
            /*
        // C# to convert a byte array to a string.
        byte [] dBytes = ...
        string str;
        System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
        str = enc.GetString(dBytes);
             */
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// C# to convert an alphnumeric string to an integer
        /// </summary>
        public static int AlphanumericStringToInt(string s)
        {
            int i;
            System.Text.Encoding ascii;
            Byte[] encodedBytes;
 
            i = 0;
            ascii = System.Text.Encoding.ASCII;
            encodedBytes = ascii.GetBytes(s);
 
            foreach (Byte b in encodedBytes) i += b;
 
            return i;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static int IncrementArrayListIndexOrRestart(ArrayList list, int currentIndex)
        {
            int newIndex;
 
            if (currentIndex < list.Count - 1) newIndex = ++currentIndex;
            else newIndex = 0;
 
            return newIndex;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static int IncrementListIndexOrRestart<T>(List<T> list, int currentIndex)
        {
            int newIndex;
 
            if (currentIndex < list.Count - 1) newIndex = ++currentIndex;
            else newIndex = 0;
 
            return newIndex;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static void IncrementIndexOrReset(int listCount, ref int currentIndex)
        {
            currentIndex = (currentIndex < listCount - 1) ? ++currentIndex : 0;
        }
 
        /*
        ////////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///
        /// </summary>
        public static void ShuffleArrayList(ArrayList al)
        {
            for (int inx = al.Count - 1; inx > 0; --inx)
            {
                int position = r.Next(inx);
                object temp = al[inx];
                al[inx] = al[position];
                al[position] = temp;
            }
        }
         */
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList ShuffleArrayList(ArrayList inputList)
        {
            ArrayList randomList = new ArrayList();
 
            int randomIndex = 0;
 
            while (inputList.Count > 0)
            {
                randomIndex = random.Next(0, inputList.Count); //Choose a random object in the list
                randomList.Add(inputList[randomIndex]); //add it to the new, random list
                inputList.RemoveAt(randomIndex); //remove to avoid duplicates
            }
 
            return randomList; //return the new random list
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static ArrayList IntegerListRange(ArrayList a_al)
        {
            // this will take an ArrayList of integer, remove duplicates, sort, then construct an ArrayList with ranges defined, if available. For example
            // a_al = [1,2,4,6,7,15,20,21,22,34,35,36,38]
            // b_al = [1,2,4,6,7,15,20-22,34-36,38]
 
            bool range, range_old;
            int u, v;
            int start, end;
            ArrayList b_al, c_al;
            Hashtable ht;
 
            // a_al = [1,2,4,6,7,15,20,21,22,34,35,36,38]
            // b_al = [1,2,4,6,7,15,20-22,34-36,38]
 
            start = end = 0;
 
            b_al = new ArrayList(a_al.Count + 1);
            c_al = new ArrayList(a_al.Count + 1);
 
            if (a_al.Count > 0)
            {
                // remove duplicates
                ht = new Hashtable(a_al.Count + 1);
 
                foreach (int i in a_al) ht[i] = 1;
 
                foreach (int i in ht.Keys) b_al.Add(i);
 
                // sort
                b_al.Sort();
 
                if (b_al.Count > 0)
                {
                    range = range_old = false;
                    u = (int)b_al[0];
 
                    for (int i = 1; i <= b_al.Count; i++)
                    {
                        if (i < b_al.Count) v = (int)b_al[i];
                        else v = (int)b_al[i - 1];
 
                        if (v - u == 1)
                        {
                            if (range) end = v;
                            else
                            {
                                start = u;
                                range = true;
                            }
                        }
                        else
                        {
                            if (range)
                            {
                                end = u;
                                range = false;
                            }
                            else c_al.Add(u.ToString());
                        }
 
                        if (range != range_old && range == false)
                        {
                            if (end - start == 1)
                            {
                                c_al.Add(start.ToString());
                                c_al.Add(end.ToString());
                            }
                            else c_al.Add(start + "-" + end);
                        }
 
                        u = v;
                        range_old = range;
                    }
                }
                else
                {
 
                }
            }
            else
            {
            }
 
            return c_al;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate a list of start-end count optimized to read around count number of values from passed number string list. 
        /// </summary>
        public static List<Tuple<string, string>> OptimizedStartEndRangeTupleList(List<string> list, int count)
        {
            bool done;
            int c;
            string start, end;
            Tuple<string, string> tuple;
            List<Tuple<string, string>> tupleList;
 
            tupleList = new List<Tuple<string, string>>();
 
            done = false;
            c = 0;
            start = string.Empty;
 
            if (list.Count > 0 && count > 0)
            {
                foreach (string s in list)
                {
                    if (c == 0)
                    {
                        start = s;
                        done = false;
                    }
 
                    if (c == count - 1)
                    {
                        end = s;
 
                        tuple = new Tuple<string, string>(start, end);
 
                        tupleList.Add(tuple);
 
                        done = true;
                        c = 0;
                    }
                    else c++;
                }
 
                if (!done)
                {
                    end = list[list.Count - 1];
 
                    tuple = new Tuple<string, string>(start, end);
 
                    tupleList.Add(tuple);
                }
            }
            else throw new System.ArgumentException("List empty or range too short. ");
 
            tupleList.Sort();
 
            return tupleList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate a list of start-end count optimized to read around count number of values from passed list. 
        /// </summary>
        public static List<Tuple<int, int>> OptimizedStartEndRangeTupleList(List<int> list, int count)
        {
            bool done;
            int c, start, end;
            Tuple<int, int> tuple;
            List<Tuple<int, int>> tupleList;
 
            tupleList = new List<Tuple<int, int>>();
 
            done = false;
            c = start = 0;
 
            if (list.Count > 0 && count > 0)
            {
                foreach (int i in list)
                {
                    if (c == 0)
                    {
                        start = i;
                        done = false;
                    }
 
                    if (c == count - 1)
                    {
                        end = i;
 
                        tuple = new Tuple<int, int>(start, end);
 
                        tupleList.Add(tuple);
 
                        done = true;
                        c = 0;
                    }
                    else c++;
                }
 
                if (!done)
                {
                    end = list[list.Count - 1];
 
                    tuple = new Tuple<int, int>(start, end);
 
                    tupleList.Add(tuple);
                }
            }
            else throw new System.ArgumentException("List empty or range too short. ");
 
            tupleList.Sort();
 
            return tupleList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate a OptimizedStartEndRangeList() but with a range buffer before start and after end.
        /// </summary>
        public static List<Tuple<int, int>> OptimizedStartEndRangeBufferedList(List<int> list, int count, int bufferRange)
        {
            int start, end;
            List<Tuple<int, int>> tupleList;
 
            tupleList = OptimizedStartEndRangeTupleList(list, count);
 
            if (tupleList != null && tupleList.Count > 0)
            {
                start = tupleList[0].Item1;
                end = tupleList[tupleList.Count - 1].Item1;
 
                tupleList.Insert(0, new Tuple<int, int>(start - bufferRange, start - 1));
                tupleList.Insert(tupleList.Count - 1, new Tuple<int, int>(end + 1, end + bufferRange + 1));
            }
 
            tupleList.Sort();
 
            return tupleList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate a list of start, end points of all integer ranges with given start, end and range. End included in range.
        /// </summary>
        public static List<Tuple<int, int>> StartEndRangeList(int start, int end, int range)
        {
            Tuple<int, int> tuple;
            List<Tuple<int, int>> tupleList;
 
            tupleList = new List<Tuple<int, int>>();
 
            if (end > start && range < (end - start))
            {
                for (int i = start; i <= end; i += range)
                {
                    if (i + range - 1 < end) tuple = new Tuple<int, int>(i, i + range - 1);
                    else tuple = new Tuple<int, int>(i, end);
 
                    tupleList.Add(tuple);
                }
            }
            else throw new System.ArgumentException("Start, end, or range is/are invalid. ");
 
            tupleList.Sort();
 
            return tupleList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate a StartEndRangeList() but with a range buffer before start and after end.
        /// </summary>
        public static List<Tuple<int, int>> StartEndRangeBufferedList(int start, int end, int range, int bufferRange)
        {
            List<Tuple<int, int>> tupleList;
 
            tupleList = StartEndRangeList(start, end, range);
 
            if (tupleList != null && tupleList.Count > 0)
            {
                tupleList.Insert(0, new Tuple<int, int>(start - bufferRange, start - 1));
                tupleList.Insert(tupleList.Count - 1, new Tuple<int, int>(end + 1, end + bufferRange + 1));
            }
 
            tupleList.Sort();
 
            return tupleList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> ConvertHyphenAndCommaSeperatedNumberStringToNumberList(string listStringAbbriviation)
        {
            int j, start, end;
            string abbriviation, u;
            List<int> list;
            MatchCollection matchCollection;
 
            // change number range (e.g. "1-5") to comma seperated numbers like "1,2,3,4,5"
 
            list = new List<int>();
 
            abbriviation = listStringAbbriviation;
 
            matchCollection = Regex.Matches(abbriviation, @"(\d{1,4})\-(\d{1,4})");
 
            foreach (Match match in matchCollection)
            {
                start = int.Parse(match.Groups[1].Value);
                end = int.Parse(match.Groups[2].Value);
 
                u = "";
                for (int i = start; i <= end; i++) u += i + ",";
 
                u = u.TrimEnd(',');
 
                // remove the matched string from the main string
                abbriviation = abbriviation.Replace(match.Groups[0].Value, u);
            }
 
            foreach (string s in abbriviation.Split(','))
            {
                if (int.TryParse(s, out j)) list.Add(j);
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// <see href="https://stackoverflow.com/questions/7688881/convert-list-to-number-range-string"/>
        /// </summary>
        public static string ConvertNumberListToHyphenAndCommaSeperatedNumberString(List<int> numberList)
        {
            return NumberListToPossiblyDegenerateRanges(numberList).Select(r => PrettyRange(r)).Intersperse(",");
        }
 
        private static IEnumerable<Tuple<int, int>> NumberListToPossiblyDegenerateRanges(IEnumerable<int> numList)
        {
            Tuple<int, int> currentRange = null;
 
            foreach (var num in numList)
            {
                if (currentRange == null)
                {
                    currentRange = Tuple.Create(num, num);
                }
                else if (currentRange.Item2 == num - 1)
                {
                    currentRange = Tuple.Create(currentRange.Item1, num);
                }
                else
                {
                    yield return currentRange;
                    currentRange = Tuple.Create(num, num);
                }
            }
            if (currentRange != null)
            {
                yield return currentRange;
            }
        }
 
        private static string PrettyRange(Tuple<int, int> range)
        {
            if (range.Item1 == range.Item2)
            {
                return range.Item1.ToString();
            }
            return string.Format("{0}-{1}", range.Item1, range.Item2);
        }
 
        private static string Intersperse(this IEnumerable<string> items, string interspersand)
        {
            var currentInterspersand = "";
            var result = new StringBuilder();
 
            foreach (var item in items)
            {
                result.Append(currentInterspersand);
                result.Append(item);
                currentInterspersand = interspersand;
            }
 
            return result.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string NumberListToCommaSeperatedNumberString(List<int> numberList)
        {
            string s;
 
            if (numberList != null && numberList.Count > 0)
            {
                s = string.Join(",", numberList.Select(n => n.ToString()).ToArray());
            }
            else s = null;
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> CommaSeperatedNumberStringToNumberList(string numberListString)
        {
            List<int> numberList;
 
            if (!string.IsNullOrEmpty(numberListString))
            {
                numberList = (numberListString != string.Empty) ? numberListString.Split(',').Select(Int32.Parse).ToList() : null;
                numberList.Sort();
            }
            else numberList = new List<int>();
 
            return numberList;
        }
 
        /*
        ////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Generate HTML table from list of generic class with specified properties
        /// <see href="http://stackoverflow.com/questions/11126137/generate-html-table-from-list-of-generic-class-with-specified-properties"/>
        /// </summary>
        public static string GenerateHtmlTableFromListOfGenericClass<T>(IEnumerable<T> list, List<string> columnNameList, params Func<T, object>[] fxns)
        {
            StringBuilder sb;
            sb = new StringBuilder();
            sb.Append("<table>\n");
            // column names
            if (columnNameList.Count > 0)
            {
                sb.Append("<tr>");
                foreach (string column in columnNameList)
                {
                    sb.Append("<td>");
                    sb.Append(column);
                    sb.Append("</td>");
                }
                sb.Append("</tr>\n");
            }
            foreach (var item in list)
            {
                sb.Append("<tr>");
                foreach (var fxn in fxns)
                {
                    sb.Append("<td>");
                    sb.Append(fxn(item));
                    sb.Append("</td>");
                }
                sb.Append("</tr>\n");
            }
            sb.Append("</table>");
            return sb.ToString();
        }
         */
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// <see href="http://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable"/>
        /// </summary>
        public static DataTable GenerateDataTableFromGenericClassList<T>(this IList<T> data)
        {
            DataTable dataTable;
            PropertyDescriptor propertyDescriptor;
            PropertyDescriptorCollection propertyDescriptorCollection;
 
            dataTable = new DataTable();
 
            dataTable.TableName = TypeDescriptor.GetClassName(typeof(T));
            propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(T));
            object[] values = new object[propertyDescriptorCollection.Count];
 
            for (int i = 0; i < propertyDescriptorCollection.Count; i++)
            {
                propertyDescriptor = propertyDescriptorCollection[i];
 
                dataTable.Columns.Add(propertyDescriptor.Name, propertyDescriptor.PropertyType);
            }
 
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++) values[i] = propertyDescriptorCollection[i].GetValue(item);
 
                dataTable.Rows.Add(values);
            }
 
            return dataTable;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// <see href="http://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable"/>
        /// </summary>
        public static DataTable GenerateDataTableFromGenericClassList<T>(this IList<T> data, string dataTableName)
        {
            // I need to pass the dataTableName here to make the code consitant
            DataTable dataTable;
            PropertyDescriptor propertyDescriptor;
            PropertyDescriptorCollection propertyDescriptorCollection;
            Type type;
            PropertyInfo propertyInfo;
            object value;
            List<int> itemToBeRemoved;
 
            dataTable = new DataTable();
            itemToBeRemoved = new List<int>();
 
            dataTable.TableName = dataTableName; //TypeDescriptor.GetClassName(typeof(T));
 
            propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(T));
            List<object> valueList = new List<object>(propertyDescriptorCollection.Count);
 
            for (int i = 0; i < propertyDescriptorCollection.Count; i++)
            {
                propertyDescriptor = propertyDescriptorCollection[i];
 
                // Important: to handle complicated EF variables that represent foreign keys. I will check the property's full name, if it starts with "Ia."
                // then this is a complicated foreign key variables that most likely points to an Id in another table, and I will attach a "_Id" suffix to the name and pass it into the DataTable.
                // Also we will get the property type of this "Id" by checking the 0 index property of the parent property (since Id is almost always the first element)
 
                if (propertyDescriptor.PropertyType.FullName.StartsWith("Ia."))
                {
                    dataTable.Columns.Add(propertyDescriptor.Name + "_Id", TypeDescriptor.GetProperties(propertyDescriptor.PropertyType)[0].PropertyType);
                }
                else if (propertyDescriptor.PropertyType.FullName.StartsWith("System.Collections.Generic.ICollection"))
                {
                    // this is a virtual property to to be converted to anything in table
                    itemToBeRemoved.Add(i);
                }
                else dataTable.Columns.Add(propertyDescriptor.Name, propertyDescriptor.PropertyType);
            }
 
            foreach (T d in data)
            {
                valueList.Clear();
 
                for (int i = 0; i < propertyDescriptorCollection.Count; i++)
                {
                    if (!itemToBeRemoved.Contains(i))
                    {
                        propertyDescriptor = propertyDescriptorCollection[i];
 
                        // below: same as above we will check to see if property full name starts with "Ia." and assign the appropriate value accordingly
 
                        if (propertyDescriptor.PropertyType.FullName.StartsWith("Ia."))
                        {
                            type = d.GetType();
 
                            propertyInfo = type.GetProperty("Designation");
 
                            if (propertyInfo != null)
                            {
                                value = propertyInfo.GetValue(d);
 
                                valueList.Add(value.GetType().GetProperty("Id").GetValue(value));
                            }
                            else
                            {
                                valueList.Add(null);
                            }
                        }
                        else valueList.Add(propertyDescriptor.GetValue(d));
                    }
                }
 
                dataTable.Rows.Add(valueList.ToArray());
            }
 
            return dataTable;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// <see href="http://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable"/>
        /// </summary>
        public static string GenerateTextFromListOfGenericClass<T>(this IList<T> data, string propertyName)
        {
            StringBuilder sb;
            PropertyDescriptor prop;
            PropertyDescriptorCollection props;
 
            sb = new StringBuilder();
            props = TypeDescriptor.GetProperties(typeof(T));
 
            object value;
 
            value = new object();
 
            foreach (T item in data)
            {
                for (int i = 0; i < props.Count; i++)
                {
                    prop = props[i];
 
                    if (propertyName == prop.Name) value = props[i].GetValue(item);
                }
 
                sb.AppendLine(value.ToString());
            }
 
            return sb.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// <see href="http://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable"/>
        /// </summary>
        public static DataTable GenerateDataTableFromListOfGenericClass<T>(this IList<T> data, params string[] propertyNameList)
        {
            int j;
            DataTable table;
            PropertyDescriptor prop;
            PropertyDescriptorCollection props;
 
            table = new DataTable();
            props = TypeDescriptor.GetProperties(typeof(T));
 
            for (int i = 0; i < props.Count; i++)
            {
                prop = props[i];
 
                if (propertyNameList.Contains(prop.Name))
                {
                    table.Columns.Add(prop.Name, prop.PropertyType);
                }
            }
 
            object[] values = new object[propertyNameList.Length];
 
            foreach (T item in data)
            {
                j = 0;
 
                for (int i = 0; i < props.Count; i++)
                {
                    prop = props[i];
 
                    if (propertyNameList.Contains(prop.Name))
                    {
                        values[j++] = props[i].GetValue(item);
                    }
                }
 
                table.Rows.Add(values);
            }
 
            return table;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate HTML table from DataTable
        /// <see href="http://stackoverflow.com/questions/19682996/datatable-to-html-table"/>
        /// </summary>
        public static string GenerateHtmlTableFromDataTable(DataTable dataTable)
        {
            StringBuilder sb;
 
            sb = new StringBuilder();
 
            sb.Append("<table>\n");
 
            // header
            sb.Append("<tr>");
 
            for (int i = 0; i < dataTable.Columns.Count; i++) sb.Append("<td>" + dataTable.Columns[i].ColumnName + "</td>");
 
            sb.Append("</tr>");
 
            // row
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                sb.Append("<tr>");
 
                for (int j = 0; j < dataTable.Columns.Count; j++) sb.Append("<td>" + dataTable.Rows[i][j].ToString() + "</td>");
 
                sb.Append("</tr>");
            }
 
            sb.Append("</table>");
 
            return sb.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate tab separated text format from DataTable
        /// </summary>
        public static string GenerateTabSeparatedTextFromDataTable(DataTable dataTable)
        {
            StringBuilder sb;
 
            sb = new StringBuilder();
 
            for (int i = 0; i < dataTable.Columns.Count; i++) sb.Append(dataTable.Columns[i].ColumnName + "\t");
 
            sb.Append("\r\n");
 
            // row
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                for (int j = 0; j < dataTable.Columns.Count; j++) sb.Append(dataTable.Rows[i][j].ToString() + "\t");
 
                sb.Append("\r\n");
            }
 
            return sb.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate DataTable from delimited text
        /// </summary>
        public static DataTable GenerateDataTableFromTabDelimitedText(string text, out Result result)
        {
            // this will only read rows that have at least 5 distinct columns
            bool first;
            string line;
            string[] columnList, lineSplit;
            DataTable dataTable;
 
            first = true;
            dataTable = new DataTable();
            result = new Result();
 
            using (StringReader reader = new StringReader(text))
            {
                while ((line = reader.ReadLine()) != null)
                {
                    // lineSplit = line.Split((string[])null, StringSplitOptions.None);
                    lineSplit = Regex.Split(line, @"\t", RegexOptions.None);
 
                    if (IsTableHeaderText(line) && first)
                    {
                        columnList = lineSplit;
 
                        foreach (var column in columnList) dataTable.Columns.Add(column);
 
                        first = false;
                    }
                    else if (!first)
                    {
                        if (lineSplit.Length == dataTable.Columns.Count)
                        {
                            dataTable.Rows.Add(lineSplit);
                        }
                        else
                        {
                            result.AddWarning("lineSplit.Length != dataTable.Columns.Count for line: " + line);
                        }
                    }
                    else
                    {
                    }
                }
            }
 
            return dataTable;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Examine a string to see if it resembles a table header string
        /// <see href="https://stackoverflow.com/questions/17812566/count-words-and-spaces-in-string-c-sharp"/>
        /// </summary>
        private static bool IsTableHeaderText(string text)
        {
            bool isHeader;
            int whitespaceCount, wordCount;
            Regex regex = new Regex(@"^[a-zA-Z\s]+$");
 
            if (!string.IsNullOrEmpty(text))
            {
                text = text.Replace("\t", "     "); // we will replace every tab with 5 spaces
 
                whitespaceCount = text.Count(Char.IsWhiteSpace);
                wordCount = CountWordsInText(text);
 
                // if the whitespace count is bigger than word count is probably a header text string
                if (whitespaceCount > 2 * wordCount)
                {
                    if (regex.IsMatch(text)) isHeader = true;
                    else isHeader = false;
                }
                else isHeader = false;
            }
            else
            {
                isHeader = false;
            }
 
            return isHeader;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static int CountWordsInText(string text)
        {
            int wordCount = 0, index = 0;
 
            while (index < text.Length)
            {
                // check if current char is part of a word
                while (index < text.Length && !char.IsWhiteSpace(text[index])) index++;
 
                wordCount++;
 
                // skip whitespace until next word
                while (index < text.Length && char.IsWhiteSpace(text[index])) index++;
            }
 
            return wordCount;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate tab separated text format from Dictionary
        /// </summary>
        public static string GenerateTabSeparatedTextFromDictionary(Dictionary<string, int> dictionary)
        {
            StringBuilder sb;
 
            sb = new StringBuilder();
 
            foreach (KeyValuePair<string, int> kvp in dictionary)
            {
                sb.AppendLine(kvp.Key + "\t" + kvp.Value);
            }
 
            return sb.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate tab separated text format from SortedDictionary
        /// </summary>
        public static string GenerateTabSeparatedTextFromDictionary(SortedDictionary<string, int> sortedDictionary)
        {
            StringBuilder sb;
 
            sb = new StringBuilder();
 
            foreach (KeyValuePair<string, int> kvp in sortedDictionary)
            {
                sb.AppendLine(kvp.Key + "\t" + kvp.Value);
            }
 
            return sb.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Generate simple two column name value table from DataTable
        /// </summary>
        public static string GenerateTwoColumnNameValueTextFromDataTable(DataTable dataTable)
        {
            StringBuilder sb;
 
            sb = new StringBuilder();
 
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    sb.Append(dataTable.Columns[j].ColumnName + ":\t" + dataTable.Rows[i][j].ToString() + "\r\n");
                }
 
                sb.Append("\r\n");
            }
 
            return sb.ToString().Trim();
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// Remove non-numeric characters
        /// http://stackoverflow.com/questions/3977497/stripping-out-non-numeric-characters-in-string
        /// </summary>
        public static string RemoveNonNumericCharacters(string line)
        {
            string s;
 
            if (line != null && line.Length != 0)
            {
                s = new string(line.Where(c => char.IsDigit(c)).ToArray());
                //s = Regex.Replace(line, "[^0-9]", "");
            }
            else s = line;
 
            return s;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// <remarks>http://stackoverflow.com/questions/2475795/check-for-missing-number-in-sequence</remarks>
        /// </summary>
        public static List<int> ExcludedNumberListFromNumberListWithinRange(List<int> list, int listSize)
        {
            // Check for missing number in sequence
            List<int> exclusionList;
 
            exclusionList = Enumerable.Range(1, listSize).Except(list).ToList();
 
            return exclusionList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static string AutoGeneratedCodeStartCommentString
        {
            get
            {
                string s;
 
                s = @"<!-- auto generated: start: This section was generated by code. Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. -->";
 
                return s;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static string AutoGeneratedCodeEndCommentString
        {
            get
            {
                string s;
 
                s = @"<!-- auto-generated: end -->";
 
                return s;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// </summary>
        public static int LevenshteinDistance(string s, string t)
        {
            if (string.IsNullOrEmpty(s))
            {
                if (string.IsNullOrEmpty(t)) return 0;
 
                return t.Length;
            }
 
            if (string.IsNullOrEmpty(t))
            {
                return s.Length;
            }
 
            int n = s.Length;
            int m = t.Length;
            int[,] d = new int[n + 1, m + 1];
 
            // initialize the top and right of the table to 0, 1, 2, ...
            for (int i = 0; i <= n; d[i, 0] = i++) ;
            for (int j = 1; j <= m; d[0, j] = j++) ;
 
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
                    int min1 = d[i - 1, j] + 1;
                    int min2 = d[i, j - 1] + 1;
                    int min3 = d[i - 1, j - 1] + cost;
                    d[i, j] = Math.Min(Math.Min(min1, min2), min3);
                }
            }
 
            return d[n, m];
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
    }
 
#if WFA
    ////////////////////////////////////////////////////////////////////////////
 
    /// <summary>
    ///
    /// </summary>
    public class ListItem
    {
        // I created this because Windows Forms does not have the equivalent like System.Web ListItem
 
        private string name;
        private string value;
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public ListItem(string _name, string _value)
        {
            this.name = _name;
            this.value = _value;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public string Name
        {
            get
            {
                return name;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public string Value
        {
 
            get
            {
                return value;
            }
        }
    }
#else
#endif
 
    ////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////
}