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

Integrated Applications Programming Company

Skip Navigation LinksHome » Code Library » NetworkDesignDocument

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

Network Design Document support class for Optical Fiber Network (OFN) data model.

   1:  using System;
   2:  using System.Collections;
   3:  using System.Collections.Generic;
   4:  using System.Data;
   5:  using System.IO;
   6:  using System.Linq;
   7:  using System.Reflection;
   8:  using System.Text;
   9:  using System.Text.RegularExpressions;
  10:  using System.Xml.Linq;
  11:   
  12:  namespace Ia.Ngn.Cl.Model.Data
  13:  {
  14:      ////////////////////////////////////////////////////////////////////////////
  15:   
  16:      /// <summary publish="true">
  17:      /// Network Design Document support class for Optical Fiber Network (OFN) data model.
  18:      /// </summary>
  19:      /// 
  20:      /// <remarks> 
  21:      /// Copyright © 2006-2021 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
  22:      ///
  23:      /// 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
  24:      /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  25:      ///
  26:      /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  27:      /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  28:      /// 
  29:      /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
  30:      /// 
  31:      /// Copyright notice: This notice may not be removed or altered from any source distribution.
  32:      /// </remarks> 
  33:      public static class NetworkDesignDocument
  34:      {
  35:          private static XDocument xDocument;
  36:   
  37:          private static List<string> ontIdList, ontAccessIdList;
  38:   
  39:          private static Dictionary<int, int> didToOltIdDictionary;
  40:          private static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> routerDomainToSiteDictionary, msanDomainToSiteDictionary, pstnDomainToSiteDictionary;
  41:          private static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType> pstnFiveDigitDomainToPstnExchangeTypeDictionary;
  42:          private static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> domainToRouterVendorDictionary;
  43:          private static Dictionary<string, string> ontAccessIdToOntIdDictionary, ontIdToOntAccessNameDictionary, ontAccessNameToOntAccessIdDictionary, ontAccessNameToOntIdDictionary, ontAccessIdToOntAccessNameDictionary, ontAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary, ontIpToOntAccessIdDictionary, ontAccessNameToOntIpDictionary, ontIdDictionary, ontIpDictionary, ponNameToPonIdDictionary, ontIpToPrimarySwitchImsFsdbDictionary, nokiaOntIpToPrimarySwitchImsFsdbDictionary;
  44:          private static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> ontAccessIdToOntDictionary, ontIdToOntDictionary, ontIpToOntDictionary, ontAccessNameToOntDictionary, ontPositionToOntDictionary;
  45:          private static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> ponIdToPonDictionary, ponNameToPonDictionary;
  46:          private static Dictionary<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn, List<int>> pstnToFiveDigitDomainListDictionary;
  47:   
  48:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Network> networkList;
  49:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> vendorList;
  50:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> siteList, legacySiteList;
  51:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> pstnList, legacyPstnList;
  52:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan> msanList;
  53:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX> softXList;
  54:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router> routerList;
  55:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam> oamList;
  56:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf> odfList;
  57:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> oltList;
  58:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup> ponGroupList;
  59:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> ponList;
  60:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> ontList, greenFieldOntList, brownFieldOntList;
  61:   
  62:          private static readonly object objectLock = new object();
  63:   
  64:          /// <summary/>
  65:          public enum BellcoreState { Undefined = 0, IsNr = 1, OosAu, OosMa, OosAuma };
  66:   
  67:          ////////////////////////////////////////////////////////////////////////////
  68:   
  69:          /// <summary>
  70:          ///
  71:          /// </summary>
  72:          //public NetworkDesignDocument() { }
  73:   
  74:          ////////////////////////////////////////////////////////////////////////////
  75:   
  76:          /// <summary>
  77:          ///
  78:          /// </summary>
  79:          public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntList
  80:          {
  81:              get
  82:              {
  83:                  if (ontList == null || ontList.Count == 0)
  84:                  {
  85:                      lock (objectLock)
  86:                      {
  87:                          ontList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._OntList;
  88:                      }
  89:                  }
  90:   
  91:                  return ontList;
  92:              }
  93:          }
  94:   
  95:          ////////////////////////////////////////////////////////////////////////////
  96:   
  97:          /// <summary>
  98:          ///
  99:          /// </summary>
 100:          private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> _OntList
 101:          {
 102:              get
 103:              {
 104:                  bool nokiaRouter, huaweiRouter, nokiaOdf, huaweiOdf;
 105:                  long networkNumberIpLong, ipLong, diff, l;
 106:                  string oltSymbol;
 107:   
 108:  #if DEBUG
 109:                  Dictionary<string, string> ontDictionary, /*proposedOntDictionary,*/ ipDictionary;
 110:  #endif
 111:                  Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont;
 112:                  Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Access access;
 113:                  Ia.Ngn.Cl.Model.Business.Ims.ImsBasicService imsBasicService;
 114:   
 115:                  var ontList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList.Count * 32);
 116:  #if DEBUG
 117:                  ontDictionary = new Dictionary<string, string>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList.Count * 32);
 118:                  //proposedOntDictionary = new Dictionary<string, string>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList.Count * 32);
 119:                  ipDictionary = new Dictionary<string, string>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList.Count * 32);
 120:  #endif
 121:   
 122:                  var nokiaAccessNameWithPbxList = Ia.Ngn.Cl.Model.Data.Ims.NokiaAccessNameWithPbxList;
 123:   
 124:                  foreach (var ponGroup in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonGroupList)
 125:                  {
 126:                      nokiaRouter = (ponGroup.Olt.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia) ? true : false; // false for Huawei
 127:                      huaweiRouter = !nokiaRouter;
 128:   
 129:                      nokiaOdf = (ponGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia) ? true : false; // false for Huawei
 130:                      huaweiOdf = !nokiaOdf;
 131:   
 132:                      oltSymbol = ponGroup.Olt.Symbol;
 133:   
 134:                      networkNumberIpLong = Ia.Cl.Model.Default.IpToDec(ponGroup.NetworkNumber);
 135:   
 136:                      // standard imsBasicService
 137:                      if (nokiaRouter)
 138:                      {
 139:                          if (nokiaOdf) imsBasicService = Ia.Ngn.Cl.Model.Business.Ims.NokiaImsBasicServiceItem(ponGroup);
 140:                          else imsBasicService = Ia.Ngn.Cl.Model.Business.Ims.SpecialHuaweiIpHandlingForNokiaImsBasicServiceItem(ponGroup);
 141:                      }
 142:                      else imsBasicService = Ia.Ngn.Cl.Model.Business.Ims.HuaweiImsBasicServiceItem(ponGroup);
 143:   
 144:                      foreach (var pon in ponGroup.PonList)
 145:                      {
 146:  #if DEBUG
 147:                          if (pon.Name == "ABW.144")
 148:                          {
 149:   
 150:                          }
 151:  #endif
 152:   
 153:                          for (int ontNumber = 1; ontNumber <= ponGroup.Olt.NumberOfOntsInPon; ontNumber++)
 154:                          {
 155:                              ont = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont();
 156:                              access = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Access();
 157:   
 158:                              ont.Pon = pon;
 159:   
 160:                              ont.Rack = ponGroup.Olt.Rack;
 161:                              ont.Sub = ponGroup.Olt.Sub;
 162:                              ont.CardSlot = pon.CardSlot;  // CardSlot might change for MDUs below
 163:                              ont.Port = pon.Port;
 164:   
 165:                              ont.Number = ontNumber;
 166:   
 167:                              ont.InternalNumber = (pon.Index * ponGroup.Olt.NumberOfOntsInPon) % 32 + ont.Number;
 168:   
 169:                              ont.Position = ponGroup.Olt.AmsName + "-" + ont.CardSlot + "-" + ont.Port + "-" + ont.InternalNumber;
 170:   
 171:                              access.Id = access.AccessId(ponGroup.Olt.Id, pon.Number, ont.Number);
 172:                              access.Pon = pon.Number;
 173:                              //access.ProposedPon = pon.ProposedNumber;
 174:                              access.Ont = ont.Number;
 175:   
 176:                              access.Symbol = ponGroup.Symbol;
 177:                              access.Name = ponGroup.Symbol + "." + pon.Number + "." + ont.Number;
 178:                              //access.ProposedName = ponGroup.Symbol + "." + pon.ProposedNumber + "." + ont.Number;
 179:   
 180:  #if DEBUG
 181:                              if (access.Name == "SSB.44.27")
 182:                              {
 183:   
 184:                              }
 185:  #endif
 186:   
 187:                              ont.Access = access;
 188:   
 189:                              ipLong = networkNumberIpLong + pon.PonGroupPonIndex * ponGroup.Olt.NumberOfOntsInPon + ont.Number; // or ont.InternalNumber
 190:                              diff = ipLong - networkNumberIpLong;
 191:   
 192:                              if (nokiaOdf)
 193:                              {
 194:                                  // below: skip *.*.*.0 only for Nokia ONTs
 195:                                  l = (diff - 1) / 255;
 196:   
 197:                                  ipLong += l;
 198:                              }
 199:                              else //if(huaweiOdf)
 200:                              {
 201:                                  if (nokiaRouter)
 202:                                  {
 203:                                  }
 204:                                  else //if (huaweiRouter)
 205:                                  {
 206:                                      // Huawei router and ODF. Here we will skip *.*.*.0 and *.*.*.1. Go figure!
 207:                                      ipLong += 1;
 208:                                  }
 209:                              }
 210:   
 211:                              ont.Ip = Ia.Cl.Model.Default.DecToIp((int)ipLong);
 212:   
 213:                              // ont.Id is used in functions below
 214:                              ont.Id = Ia.Ngn.Cl.Model.Business.Nokia.Ont.OntId(pon.Id, ont.InternalNumber);
 215:   
 216:                              // special imsBasicService
 217:                              if (nokiaRouter)
 218:                              {
 219:                                  if (huaweiOdf)
 220:                                  {
 221:                                      if (nokiaAccessNameWithPbxList.Contains(ont.Access.Name))
 222:                                      {
 223:                                          ont.ImsBasicService = Ia.Ngn.Cl.Model.Business.Ims.NokiaImsBasicServiceItemForAccessWithPbx(ont);
 224:                                      }
 225:                                      else ont.ImsBasicService = Ia.Ngn.Cl.Model.Business.Ims.SpecialHuaweiIpHandlingForNokiaImsBasicServiceItem(ont) ?? imsBasicService;
 226:                                  }
 227:                                  else
 228:                                  {
 229:                                      if (nokiaAccessNameWithPbxList.Contains(ont.Access.Name))
 230:                                      {
 231:                                          ont.ImsBasicService = Ia.Ngn.Cl.Model.Business.Ims.NokiaImsBasicServiceItemForAccessWithPbx(ont);
 232:                                      }
 233:                                      else ont.ImsBasicService = imsBasicService;
 234:                                  }
 235:                              }
 236:                              else ont.ImsBasicService = imsBasicService;
 237:   
 238:   
 239:  #if DEBUG
 240:                              // this will throw an exception if there is a duplicate ont.Access.Name
 241:                              if (ontDictionary.ContainsKey(ont.Access.Name))
 242:                              {
 243:                                  throw new ArgumentOutOfRangeException(@"ontDictionary.ContainsKey(ont.Access.Name)");
 244:                              }
 245:                              else ontDictionary[ont.Access.Name] = ont.Id;
 246:   
 247:                              /*
 248:                              // this will throw an exception if there is a duplicate ont.Access.ProposedName
 249:                              if (proposedOntDictionary.ContainsKey(ont.Access.ProposedName))
 250:                              {
 251:                                  throw new ArgumentOutOfRangeException(@"proposedOntDictionary.ContainsKey(ont.Access.ProposedName)");
 252:                              }
 253:                              else proposedOntDictionary[ont.Access.ProposedName] = ont.Id;
 254:                              */
 255:   
 256:                              /*
 257:                              // this will throw an exception if an IP has *.*.*.0
 258:                              // over 400 Huawei ONTs with *.*.*.0 IPs
 259:                              if (Regex.IsMatch(ont.Ip, @"\d{1,3}\.\d{1,3}\.\d{1,3}\.0"))
 260:                              {
 261:                                  list.Add(ont.Access.Name);
 262:                              }
 263:                              */
 264:   
 265:                              // this will throw an exception if there is a duplicate ont.Ip
 266:                              if (ipDictionary.ContainsKey(ont.Ip))
 267:                              {
 268:                                  throw new ArgumentOutOfRangeException(@"ipDictionary.ContainsKey(ont.Ip)");
 269:                              }
 270:                              else ipDictionary[ont.Ip] = ont.Id;
 271:  #endif
 272:                              ontList.Add(ont);
 273:                          }
 274:                      }
 275:                  }
 276:   
 277:                  // as a precaution, this will throw an exception if there are not n number of records
 278:                  if (ontList.Count != Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PrecautionaryHardCodedNumberOfOntRecords)
 279:                  {
 280:                      throw new ArgumentOutOfRangeException(@"(ontList.Count != " + Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PrecautionaryHardCodedNumberOfOntRecords);
 281:                  }
 282:   
 283:                  return ontList;
 284:              }
 285:          }
 286:   
 287:          ////////////////////////////////////////////////////////////////////////////
 288:   
 289:          /// <summary>
 290:          /// 
 291:          /// </summary>
 292:          public static List<string> OntIdList
 293:          {
 294:              get
 295:              {
 296:                  if (ontIdList == null || ontIdList.Count == 0)
 297:                  {
 298:                      lock (objectLock)
 299:                      {
 300:                          ontIdList = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 301:                                       orderby o.Id
 302:                                       select o.Id).ToList();
 303:                      }
 304:                  }
 305:   
 306:                  return ontIdList;
 307:              }
 308:          }
 309:   
 310:          ////////////////////////////////////////////////////////////////////////////
 311:   
 312:          /// <summary>
 313:          /// 
 314:          /// </summary>
 315:          public static List<string> OntAccessIdList
 316:          {
 317:              get
 318:              {
 319:                  if (ontAccessIdList == null || ontAccessIdList.Count == 0)
 320:                  {
 321:                      lock (objectLock)
 322:                      {
 323:                          ontAccessIdList = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 324:                                             orderby o.Access.Id
 325:                                             select o.Access.Id).ToList();
 326:                      }
 327:                  }
 328:   
 329:                  return ontAccessIdList;
 330:              }
 331:          }
 332:   
 333:          ////////////////////////////////////////////////////////////////////////////
 334:   
 335:          /// <summary>
 336:          ///
 337:          /// </summary>
 338:          public static Dictionary<string, string> OntAccessIdToOntIdDictionary
 339:          {
 340:              get
 341:              {
 342:                  if (ontAccessIdToOntIdDictionary == null || ontAccessIdToOntIdDictionary.Count == 0)
 343:                  {
 344:                      lock (objectLock)
 345:                      {
 346:                          ontAccessIdToOntIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 347:                                                          select new { AccessId = o.Access.Id, OntId = o.Id }).ToDictionary(n => n.AccessId, n => n.OntId);
 348:                      }
 349:                  }
 350:   
 351:                  return ontAccessIdToOntIdDictionary;
 352:              }
 353:          }
 354:   
 355:          ////////////////////////////////////////////////////////////////////////////
 356:   
 357:          /// <summary>
 358:          ///
 359:          /// </summary>
 360:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntAccessIdToOntDictionary
 361:          {
 362:              get
 363:              {
 364:                  if (ontAccessIdToOntDictionary == null || ontAccessIdToOntDictionary.Count == 0)
 365:                  {
 366:                      lock (objectLock)
 367:                      {
 368:                          ontAccessIdToOntDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 369:                                                        select new { AccessId = o.Access.Id, Ont = o }).ToDictionary(n => n.AccessId, n => n.Ont);
 370:                      }
 371:                  }
 372:   
 373:                  return ontAccessIdToOntDictionary;
 374:              }
 375:          }
 376:   
 377:          ////////////////////////////////////////////////////////////////////////////
 378:   
 379:          /// <summary>
 380:          ///
 381:          /// </summary>
 382:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntIpToOntDictionary
 383:          {
 384:              get
 385:              {
 386:                  if (ontIpToOntDictionary == null || ontIpToOntDictionary.Count == 0)
 387:                  {
 388:                      lock (objectLock)
 389:                      {
 390:                          ontIpToOntDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 391:                                                  select new { Ip = o.Ip, Ont = o }).ToDictionary(n => n.Ip, n => n.Ont);
 392:                      }
 393:                  }
 394:   
 395:                  return ontIpToOntDictionary;
 396:              }
 397:          }
 398:   
 399:          ////////////////////////////////////////////////////////////////////////////
 400:   
 401:          /// <summary>
 402:          ///
 403:          /// </summary>
 404:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntAccessIdToOntForOltIdListDictionary(List<int> oltIdList)
 405:          {
 406:              lock (objectLock)
 407:              {
 408:                  var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 409:                              where oltIdList.Contains(o.Pon.PonGroup.Olt.Id)
 410:                              select new { AccessId = o.Access.Id, Ont = o }).ToDictionary(n => n.AccessId, n => n.Ont);
 411:   
 412:                  return list;
 413:              }
 414:          }
 415:   
 416:          ////////////////////////////////////////////////////////////////////////////
 417:   
 418:          /// <summary>
 419:          ///
 420:          /// </summary>
 421:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntIpToOntForOltIdListDictionary(List<int> oltIdList)
 422:          {
 423:              lock (objectLock)
 424:              {
 425:                  var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 426:                              where oltIdList.Contains(o.Pon.PonGroup.Olt.Id)
 427:                              select new { OntIp = o.Ip, Ont = o }).ToDictionary(n => n.OntIp, n => n.Ont);
 428:   
 429:                  return list;
 430:              }
 431:          }
 432:   
 433:          ////////////////////////////////////////////////////////////////////////////
 434:   
 435:          /// <summary>
 436:          ///
 437:          /// </summary>
 438:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntAccessIdToOntForOltSymbolListDictionary(List<string> oltSymbolList)
 439:          {
 440:              lock (objectLock)
 441:              {
 442:                  var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 443:                              where oltSymbolList.Contains(o.Pon.PonGroup.Olt.Symbol)
 444:                              select new { AccessId = o.Access.Id, Ont = o }).ToDictionary(n => n.AccessId, n => n.Ont);
 445:   
 446:                  return list;
 447:              }
 448:          }
 449:   
 450:          ////////////////////////////////////////////////////////////////////////////
 451:   
 452:          /// <summary>
 453:          ///
 454:          /// </summary>
 455:          public static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> RouterDomainToSiteDictionary
 456:          {
 457:              get
 458:              {
 459:                  if (routerDomainToSiteDictionary == null || routerDomainToSiteDictionary.Count == 0)
 460:                  {
 461:                      lock (objectLock)
 462:                      {
 463:                          routerDomainToSiteDictionary = new Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site>();
 464:   
 465:                          var routerList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.RouterList;
 466:   
 467:                          foreach (int domain in routerList.SelectMany(u => u.DomainList))
 468:                          {
 469:                              routerDomainToSiteDictionary[domain] = (from r in routerList where r.DomainList.Contains(domain) select r.Site).FirstOrDefault(); //.SingleOrDefault(); see NDD XML with domain 2390, has two sites
 470:                          }
 471:                      }
 472:                  }
 473:   
 474:                  return routerDomainToSiteDictionary;
 475:              }
 476:          }
 477:   
 478:          ////////////////////////////////////////////////////////////////////////////
 479:   
 480:          /// <summary>
 481:          ///
 482:          /// </summary>
 483:          public static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> MsanDomainToSiteDictionary
 484:          {
 485:              get
 486:              {
 487:                  if (msanDomainToSiteDictionary == null || msanDomainToSiteDictionary.Count == 0)
 488:                  {
 489:                      lock (objectLock)
 490:                      {
 491:                          msanDomainToSiteDictionary = new Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site>();
 492:   
 493:                          var msanList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.MsanList;
 494:   
 495:                          foreach (int domain in msanList.SelectMany(u => u.DomainList))
 496:                          {
 497:                              msanDomainToSiteDictionary[domain] = (from m in msanList where m.DomainList.Contains(domain) select m.Site).FirstOrDefault(); //.SingleOrDefault();
 498:                          }
 499:                      }
 500:                  }
 501:   
 502:                  return msanDomainToSiteDictionary;
 503:              }
 504:          }
 505:   
 506:          ////////////////////////////////////////////////////////////////////////////
 507:   
 508:          /// <summary>
 509:          ///
 510:          /// </summary>
 511:          public static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> PstnDomainToSiteDictionary
 512:          {
 513:              get
 514:              {
 515:                  if (pstnDomainToSiteDictionary == null || pstnDomainToSiteDictionary.Count == 0)
 516:                  {
 517:                      lock (objectLock)
 518:                      {
 519:                          pstnDomainToSiteDictionary = new Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site>();
 520:   
 521:                          var pstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList;
 522:   
 523:                          foreach (int domain in pstnList.SelectMany(u => u.DomainList))
 524:                          {
 525:                              pstnDomainToSiteDictionary[domain] = (from p in pstnList where p.DomainList.Contains(domain) select p.Site).SingleOrDefault();
 526:                          }
 527:                      }
 528:                  }
 529:   
 530:                  return pstnDomainToSiteDictionary;
 531:              }
 532:          }
 533:   
 534:          ////////////////////////////////////////////////////////////////////////////
 535:   
 536:          /// <summary>
 537:          ///
 538:          /// </summary>
 539:          public static Dictionary<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn, List<int>> PstnToFiveDigitDomainListDictionary()
 540:          {
 541:              if (pstnToFiveDigitDomainListDictionary == null || pstnToFiveDigitDomainListDictionary.Count == 0)
 542:              {
 543:                  lock (objectLock)
 544:                  {
 545:                      pstnToFiveDigitDomainListDictionary = new Dictionary<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn, List<int>>();
 546:   
 547:                      var pstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList;
 548:   
 549:                      foreach (var pstn in pstnList)
 550:                      {
 551:                          var list = new List<int>();
 552:   
 553:                          foreach (int domain in pstn.DomainList)
 554:                          {
 555:                              // already five digit domain
 556:                              if (domain > 9999) list.Add(domain);
 557:                              else
 558:                              {
 559:                                  // four digit domain, we will need to create five digit domains related to it
 560:                                  for (int i = 0; i <= 9; i++)
 561:                                  {
 562:                                      list.Add(domain * 10 + i);
 563:                                  }
 564:                              }
 565:   
 566:                              pstnToFiveDigitDomainListDictionary[pstn] = list;
 567:                          }
 568:                      }
 569:                  }
 570:              }
 571:   
 572:              return pstnToFiveDigitDomainListDictionary;
 573:          }
 574:   
 575:          ////////////////////////////////////////////////////////////////////////////
 576:   
 577:          /// <summary>
 578:          ///
 579:          /// </summary>
 580:          public static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType> PstnFiveDigitDomainToVendorDictionary()
 581:          {
 582:              if (pstnFiveDigitDomainToPstnExchangeTypeDictionary == null || pstnFiveDigitDomainToPstnExchangeTypeDictionary.Count == 0)
 583:              {
 584:                  lock (objectLock)
 585:                  {
 586:                      pstnFiveDigitDomainToPstnExchangeTypeDictionary = new Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType>();
 587:   
 588:                      var pstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList;
 589:   
 590:                      foreach (var pstn in pstnList)
 591:                      {
 592:                          foreach (int domain in pstn.DomainList)
 593:                          {
 594:                              // already five digit domain
 595:                              if (domain > 9999) pstnFiveDigitDomainToPstnExchangeTypeDictionary[domain] = pstn.PstnExchangeType;
 596:                              else
 597:                              {
 598:                                  // four digit domain, we will need to create five digit domains related to it
 599:                                  for (int i = 0; i <= 9; i++)
 600:                                  {
 601:                                      pstnFiveDigitDomainToPstnExchangeTypeDictionary[domain * 10 + i] = pstn.PstnExchangeType;
 602:                                  }
 603:                              }
 604:                          }
 605:                      }
 606:                  }
 607:              }
 608:   
 609:              return pstnFiveDigitDomainToPstnExchangeTypeDictionary;
 610:          }
 611:   
 612:          ////////////////////////////////////////////////////////////////////////////
 613:   
 614:          /// <summary>
 615:          ///
 616:          /// </summary>
 617:          public static Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> DomainToRouterVendorDictionary
 618:          {
 619:              get
 620:              {
 621:                  if (domainToRouterVendorDictionary == null || domainToRouterVendorDictionary.Count == 0)
 622:                  {
 623:                      lock (objectLock)
 624:                      {
 625:                          domainToRouterVendorDictionary = new Dictionary<int, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor>();
 626:   
 627:                          var routerList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.RouterList;
 628:   
 629:                          foreach (int domain in routerList.SelectMany(u => u.DomainList))
 630:                          {
 631:                              domainToRouterVendorDictionary[domain] = (from r in routerList
 632:                                                                        where r.DomainList.Contains(domain)
 633:                                                                        select r.Vendor).FirstOrDefault(); //.SingleOrDefault(); see NDD XML with domain 2390, has two sites
 634:                          }
 635:                      }
 636:                  }
 637:   
 638:                  return domainToRouterVendorDictionary;
 639:              }
 640:          }
 641:   
 642:          ////////////////////////////////////////////////////////////////////////////
 643:   
 644:          /// <summary>
 645:          ///
 646:          /// </summary>
 647:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntIdToOntDictionary
 648:          {
 649:              get
 650:              {
 651:                  if (ontIdToOntDictionary == null || ontIdToOntDictionary.Count == 0)
 652:                  {
 653:                      lock (objectLock)
 654:                      {
 655:                          ontIdToOntDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 656:                                                  select new { OntId = o.Id, Ont = o }).ToDictionary(n => n.OntId, n => n.Ont);
 657:                      }
 658:                  }
 659:                  return ontIdToOntDictionary;
 660:              }
 661:          }
 662:   
 663:          ////////////////////////////////////////////////////////////////////////////
 664:   
 665:          /// <summary>
 666:          ///
 667:          /// </summary>
 668:          public static Dictionary<string, string> OntIdToOntAccessNameDictionary
 669:          {
 670:              get
 671:              {
 672:                  if (ontIdToOntAccessNameDictionary == null || ontIdToOntAccessNameDictionary.Count == 0)
 673:                  {
 674:                      lock (objectLock)
 675:                      {
 676:                          ontIdToOntAccessNameDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 677:                                                            select new { OntId = o.Id, OntAccessName = o.Access.Name }).ToDictionary(n => n.OntId, n => n.OntAccessName);
 678:                      }
 679:                  }
 680:   
 681:                  return ontIdToOntAccessNameDictionary;
 682:              }
 683:          }
 684:   
 685:          ////////////////////////////////////////////////////////////////////////////
 686:   
 687:          /// <summary>
 688:          ///
 689:          /// </summary>
 690:          public static Dictionary<string, string> OntAccessNameToOntIdDictionary
 691:          {
 692:              get
 693:              {
 694:                  if (ontAccessNameToOntIdDictionary == null || ontAccessNameToOntIdDictionary.Count == 0)
 695:                  {
 696:                      lock (objectLock)
 697:                      {
 698:                          ontAccessNameToOntIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 699:                                                            select new { OntAccessName = o.Access.Name, OntId = o.Id }).ToDictionary(n => n.OntAccessName, n => n.OntId);
 700:                      }
 701:                  }
 702:   
 703:                  return ontAccessNameToOntIdDictionary;
 704:              }
 705:          }
 706:   
 707:          ////////////////////////////////////////////////////////////////////////////
 708:   
 709:          /// <summary>
 710:          ///
 711:          /// </summary>
 712:          public static Dictionary<string, string> OntAccessNameToOntAccessIdDictionary
 713:          {
 714:              get
 715:              {
 716:                  if (ontAccessNameToOntAccessIdDictionary == null || ontAccessNameToOntAccessIdDictionary.Count == 0)
 717:                  {
 718:                      lock (objectLock)
 719:                      {
 720:                          ontAccessNameToOntAccessIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 721:                                                                  select new { OntAccessName = o.Access.Name, OntAccessId = o.Access.Id }).ToDictionary(n => n.OntAccessName, n => n.OntAccessId);
 722:                      }
 723:                  }
 724:   
 725:                  return ontAccessNameToOntAccessIdDictionary;
 726:              }
 727:          }
 728:   
 729:          ////////////////////////////////////////////////////////////////////////////
 730:   
 731:          /// <summary>
 732:          ///
 733:          /// </summary>
 734:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntAccessNameToOntDictionary
 735:          {
 736:              get
 737:              {
 738:                  if (ontAccessNameToOntDictionary == null || ontAccessNameToOntDictionary.Count == 0)
 739:                  {
 740:                      lock (objectLock)
 741:                      {
 742:                          ontAccessNameToOntDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 743:                                                          select new { OntAccessName = o.Access.Name, Ont = o }).ToDictionary(n => n.OntAccessName, n => n.Ont);
 744:                      }
 745:                  }
 746:   
 747:                  return ontAccessNameToOntDictionary;
 748:              }
 749:          }
 750:   
 751:          ////////////////////////////////////////////////////////////////////////////
 752:   
 753:          /// <summary>
 754:          ///
 755:          /// </summary>
 756:          public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> OntPositionToOntDictionary
 757:          {
 758:              get
 759:              {
 760:                  if (ontPositionToOntDictionary == null || ontPositionToOntDictionary.Count == 0)
 761:                  {
 762:                      lock (objectLock)
 763:                      {
 764:                          ontPositionToOntDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 765:                                                        select new { OntPosition = o.Position, Ont = o }).ToDictionary(n => n.OntPosition, n => n.Ont);
 766:                      }
 767:                  }
 768:   
 769:                  return ontPositionToOntDictionary;
 770:              }
 771:          }
 772:   
 773:          ////////////////////////////////////////////////////////////////////////////
 774:   
 775:          /// <summary>
 776:          ///
 777:          /// </summary>
 778:          public static Dictionary<string, string> OntAccessIdToOntAccessNameDictionary
 779:          {
 780:              get
 781:              {
 782:                  if (ontAccessIdToOntAccessNameDictionary == null || ontAccessIdToOntAccessNameDictionary.Count == 0)
 783:                  {
 784:                      lock (objectLock)
 785:                      {
 786:                          ontAccessIdToOntAccessNameDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 787:                                                                  select new { OntAccessId = o.Access.Id, OntAccessName = o.Access.Name }).ToDictionary(n => n.OntAccessId, n => n.OntAccessName);
 788:                      }
 789:                  }
 790:   
 791:                  return ontAccessIdToOntAccessNameDictionary;
 792:              }
 793:          }
 794:   
 795:          ////////////////////////////////////////////////////////////////////////////
 796:   
 797:          /// <summary>
 798:          ///
 799:          /// </summary>
 800:          public static Dictionary<string, string> OntAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary
 801:          {
 802:              get
 803:              {
 804:                  if (ontAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary == null || ontAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary.Count == 0)
 805:                  {
 806:                      lock (objectLock)
 807:                      {
 808:                          var allowedToBeMigratedOltIdList = Ia.Ngn.Cl.Model.Data.Service.AllowedToBeMigratedOltIdList;
 809:   
 810:                          ontAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 811:                                                                                              where allowedToBeMigratedOltIdList.Contains(o.Pon.PonGroup.Olt.Id)
 812:                                                                                              select new { OntAccessId = o.Access.Id, OntAccessName = o.Access.Name }).ToDictionary(n => n.OntAccessId, n => n.OntAccessName);
 813:                      }
 814:                  }
 815:   
 816:                  return ontAccessIdToOntAccessNameWithinAllowedToBeMigratedOltDictionary;
 817:              }
 818:          }
 819:   
 820:          ////////////////////////////////////////////////////////////////////////////
 821:   
 822:          /// <summary>
 823:          ///
 824:          /// </summary>
 825:          public static Dictionary<string, string> OntIpToOntAccessIdDictionary
 826:          {
 827:              get
 828:              {
 829:                  if (ontIpToOntAccessIdDictionary == null || ontIpToOntAccessIdDictionary.Count == 0)
 830:                  {
 831:                      lock (objectLock)
 832:                      {
 833:                          ontIpToOntAccessIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 834:                                                          select new { OntIp = o.Ip, OntAccessId = o.Access.Id }).ToDictionary(n => n.OntIp, n => n.OntAccessId);
 835:                      }
 836:                  }
 837:   
 838:                  return ontIpToOntAccessIdDictionary;
 839:              }
 840:          }
 841:   
 842:          ////////////////////////////////////////////////////////////////////////////
 843:   
 844:          /// <summary>
 845:          ///
 846:          /// </summary>
 847:          public static Dictionary<string, string> OntAccessNameToOntIpDictionary
 848:          {
 849:              get
 850:              {
 851:                  if (ontAccessNameToOntIpDictionary == null || ontAccessNameToOntIpDictionary.Count == 0)
 852:                  {
 853:                      lock (objectLock)
 854:                      {
 855:                          ontAccessNameToOntIpDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 856:                                                            select new { OntAccessName = o.Access.Name, OntIp = o.Ip }).ToDictionary(n => n.OntAccessName, n => n.OntIp);
 857:                      }
 858:                  }
 859:   
 860:                  return ontAccessNameToOntIpDictionary;
 861:              }
 862:          }
 863:   
 864:          ////////////////////////////////////////////////////////////////////////////
 865:   
 866:          /// <summary>
 867:          ///
 868:          /// </summary>
 869:          public static Dictionary<string, string> OntIdDictionary
 870:          {
 871:              get
 872:              {
 873:                  if (ontIdDictionary == null || ontIdDictionary.Count == 0)
 874:                  {
 875:                      lock (objectLock)
 876:                      {
 877:                          ontIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 878:                                             select o.Id).ToDictionary(n => n, n => n);
 879:                      }
 880:                  }
 881:   
 882:                  return ontIdDictionary;
 883:              }
 884:          }
 885:   
 886:          ////////////////////////////////////////////////////////////////////////////
 887:   
 888:          /// <summary>
 889:          ///
 890:          /// </summary>
 891:          public static Dictionary<string, string> OntIpDictionary
 892:          {
 893:              get
 894:              {
 895:                  if (ontIpDictionary == null || ontIpDictionary.Count == 0)
 896:                  {
 897:                      lock (objectLock)
 898:                      {
 899:                          ontIpDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 900:                                             select o.Ip).ToDictionary(n => n, n => n);
 901:                      }
 902:                  }
 903:                  return ontIpDictionary;
 904:              }
 905:          }
 906:   
 907:          ////////////////////////////////////////////////////////////////////////////
 908:   
 909:          /// <summary>
 910:          ///
 911:          /// </summary>
 912:          public static Dictionary<string, string> OntIpToPrimarySwitchImsFsdbDictionary
 913:          {
 914:              get
 915:              {
 916:                  if (ontIpToPrimarySwitchImsFsdbDictionary == null || ontIpToPrimarySwitchImsFsdbDictionary.Count == 0)
 917:                  {
 918:                      lock (objectLock)
 919:                      {
 920:                          ontIpToPrimarySwitchImsFsdbDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 921:                                                                   select o).Distinct().ToDictionary(n => n.Ip, n => n.PrimarySwitch + " (" + n.ImsFsdb + ")");
 922:                      }
 923:                  }
 924:   
 925:                  return ontIpToPrimarySwitchImsFsdbDictionary;
 926:              }
 927:          }
 928:   
 929:          ////////////////////////////////////////////////////////////////////////////
 930:   
 931:          /// <summary>
 932:          ///
 933:          /// </summary>
 934:          public static Dictionary<string, string> NokiaOntIpToPrimarySwitchImsFsdbDictionary
 935:          {
 936:              get
 937:              {
 938:                  if (nokiaOntIpToPrimarySwitchImsFsdbDictionary == null || nokiaOntIpToPrimarySwitchImsFsdbDictionary.Count == 0)
 939:                  {
 940:                      lock (objectLock)
 941:                      {
 942:                          nokiaOntIpToPrimarySwitchImsFsdbDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
 943:                                                                        where o.Pon.PonGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
 944:                                                                        select o).Distinct().ToDictionary(n => n.Ip, n => n.PrimarySwitch + " (" + n.ImsFsdb + ")");
 945:                      }
 946:                  }
 947:   
 948:                  return nokiaOntIpToPrimarySwitchImsFsdbDictionary;
 949:              }
 950:          }
 951:   
 952:          ////////////////////////////////////////////////////////////////////////////
 953:   
 954:          /// <summary>
 955:          ///
 956:          /// </summary>
 957:          public static bool AccessNameIsWithinAllowedOntList(string inputAccessName, out string accessName)
 958:          {
 959:              // below: this checks that this accessName is within the standard possible values in network
 960:              bool isWithinAllowedOnts;
 961:   
 962:              var nddOnt = Ia.Ngn.Cl.Model.Business.Default.NddOntUsingExtractedAccessNameWithValidSymbolAndLegalFormatForPonAndOntFromValue(inputAccessName);
 963:   
 964:              if (nddOnt != null)
 965:              {
 966:                  isWithinAllowedOnts = true;
 967:                  accessName = nddOnt.Access.Name;
 968:              }
 969:              else
 970:              {
 971:                  isWithinAllowedOnts = false;
 972:                  accessName = string.Empty;
 973:              }
 974:   
 975:              return isWithinAllowedOnts;
 976:          }
 977:   
 978:          ////////////////////////////////////////////////////////////////////////////
 979:   
 980:          /// <summary>
 981:          ///
 982:          /// </summary>
 983:          public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont OntById(string ontId)
 984:          {
 985:              Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont ont;
 986:   
 987:              if (!string.IsNullOrEmpty(ontId))
 988:              {
 989:                  var d = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIdToOntDictionary;
 990:   
 991:                  if (d.ContainsKey(ontId)) ont = d[ontId];
 992:                  else ont = null;
 993:              }
 994:              else ont = null;
 995:   
 996:              return ont;
 997:          }
 998:   
 999:          ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont OntByAccessName(string accessName)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
 
            if (!string.IsNullOrEmpty(accessName))
            {
                accessName = accessName.ToUpper();
 
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
            }
            else nddOnt = null;
 
            return nddOnt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont OntByOntAccessId(string accessId)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
 
            if (!string.IsNullOrEmpty(accessId))
            {
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntDictionary.ContainsKey(accessId) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntDictionary[accessId] : null;
            }
            else nddOnt = null;
 
            return nddOnt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string AccessNameByOntId(string ontId)
        {
            string accessName;
 
            if (!string.IsNullOrEmpty(ontId))
            {
                var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIdToOntDictionary.ContainsKey(ontId) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIdToOntDictionary[ontId] : null;
 
                if (nddOnt != null)
                {
                    accessName = nddOnt.Access.Name;
                }
                else accessName = string.Empty;
            }
            else accessName = string.Empty;
 
            return accessName;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont OntByIp(string ip)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
 
            if (!string.IsNullOrEmpty(ip))
            {
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIpToOntDictionary.ContainsKey(ip) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntIpToOntDictionary[ip] : null;
            }
            else nddOnt = null;
 
            return nddOnt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> AccessVendorListByOntIdList(List<string> ontIdList)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
            var vendorList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor>();
 
            foreach (var ontId in ontIdList)
            {
                if (!string.IsNullOrEmpty(ontId))
                {
                    var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntById(ontId);
 
                    vendor = (nddOnt != null) ? nddOnt.Pon.PonGroup.Olt.Odf.Vendor : Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
                }
                else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
                vendorList.Add(vendor);
            }
 
            return vendorList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> SwitchVendorListByOntIdList(List<string> ontIdList)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
            var vendorList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor>();
 
            foreach (var ontId in ontIdList)
            {
                if (!string.IsNullOrEmpty(ontId))
                {
                    var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntById(ontId);
 
                    vendor = (nddOnt != null) ? nddOnt.Pon.PonGroup.Olt.Odf.Router.Vendor : Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
                }
                else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
                vendorList.Add(vendor);
            }
 
            return vendorList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor AccessVendorByOntAccessId(string ontAccessId)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
 
            if (!string.IsNullOrEmpty(ontAccessId))
            {
                var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntDictionary.ContainsKey(ontAccessId) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessIdToOntDictionary[ontAccessId] : null;
 
                if (nddOnt != null)
                {
                    vendor = nddOnt.Pon.PonGroup.Olt.Odf.Vendor;
                }
                else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
            }
            else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
            return vendor;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor AccessVendorByAccessName(string accessName)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
 
            if (!string.IsNullOrEmpty(accessName))
            {
                accessName = accessName.ToUpper();
 
                var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
 
                if (nddOnt != null)
                {
                    vendor = nddOnt.Pon.PonGroup.Olt.Odf.Vendor;
                }
                else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
            }
            else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
            return vendor;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor SwitchVendorByAccessName(string accessName)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor;
 
            if (!string.IsNullOrEmpty(accessName))
            {
                accessName = accessName.ToUpper();
 
                var nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary.ContainsKey(accessName) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntAccessNameToOntDictionary[accessName] : null;
 
                if (nddOnt != null)
                {
                    vendor = nddOnt.Pon.PonGroup.Olt.Odf.Router.Vendor;
                }
                else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
            }
            else vendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
            return vendor;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router RouterFromService(string service)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router router;
 
            if (!string.IsNullOrEmpty(service))
            {
                if (int.TryParse(service, out int i))
                {
                    router = (from r in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.RouterList
                              where r.DomainList.Any(u => service.StartsWith(u.ToString()))
                              select r).FirstOrDefault(); //.SingleOrDefault(); // 2390 is defined in two different huawei routers
                }
                else router = null;
            }
            else router = null;
 
            return router;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont OntByPosition(string position)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
 
            if (!string.IsNullOrEmpty(position))
            {
                nddOnt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntPositionToOntDictionary.ContainsKey(position) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntPositionToOntDictionary[position] : null;
            }
            else nddOnt = null;
 
            return nddOnt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string OntIdByPosition(string position)
        {
            string ontId;
 
            if (!string.IsNullOrEmpty(position))
            {
                var ont = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntPositionToOntDictionary.ContainsKey(position) ?
                    Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntPositionToOntDictionary[position] : null;
 
                if (ont != null) ontId = ont.Id;
                else ontId = string.Empty;
            }
            else ontId = string.Empty;
 
            return ontId;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
 
 
 
 
 
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> PonList
        {
            get
            {
                if (ponList == null || ponList.Count == 0)
                {
                    lock (objectLock)
                    {
                        ponList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._PonList;
                    }
                }
 
                return ponList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> _PonList
        {
            get
            {
                bool nokiaRouter, huaweiRouter, nokiaOdf, huaweiOdf;
                int ponNumber, slot, oltPonIndex, oltPonCount;
                //int proposedPonNumber, oltProposedPonCount;
                string odfName;
#if DEBUG
                Dictionary<string, string> ponIdDictionary;
#endif
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon;
 
                var ponList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonGroupList.Count * 32); // 32 is the max number of PONs in an PonGroup (16 max per LT)
#if DEBUG
                ponIdDictionary = new Dictionary<string, string>(Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonGroupList.Count * 32);
#endif
                foreach (var olt in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList)
                {
                    oltPonIndex = 0;
 
                    nokiaRouter = (olt.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia) ? true : false; // false for Huawei
                    huaweiRouter = !nokiaRouter;
 
                    nokiaOdf = (olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia) ? true : false; // false for Huawei
                    huaweiOdf = !nokiaOdf;
 
                    odfName = olt.Odf.Name;
 
                    oltPonCount = /*oltProposedPonCount =*/ 0;
 
                    foreach (var ponGroup in olt.PonGroupList)
                    {
                        oltPonCount += ponGroup.UsedPonInPonGroupList.Count;
 
                        //if (ponGroup.HasNewProposedPonList) oltProposedPonCount += ponGroup.UsedProposedPonInPonGroupList.Count;
                    }
 
                    //if (/*((oltPonCount == oltProposedPonCount) || oltProposedPonCount == 0) &&*/ oltPonCount % 32 == 0)
                    //{
                    foreach (var ponGroup in olt.PonGroupList)
                    {
                        //if (!ponGroup.HasNewProposedPonList || ponGroup.UsedPonInPonGroupList.Count == ponGroup.UsedProposedPonInPonGroupList.Count)
                        //{
                        // below: Note that I will use the INDEX of the PON number in the UsedPonList to construct the PON Id, this will make it possible 
                        // to match this index with that from the Ip, position list, because that list does not recognize PONs.
                        for (int ponGroupPonIndex = 0; ponGroupPonIndex < ponGroup.UsedPonInPonGroupList.Count; ponGroupPonIndex++)
                        {
                            if ((int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex] != 0)// && (!ponGroup.HasNewProposedPonList || (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex] != 0))
                            {
                                pon = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon();
 
                                ponNumber = (int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex];
 
                                //if (ponGroup.HasNewProposedPonList) proposedPonNumber = (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex];
                                //else proposedPonNumber = ponNumber;
 
                                pon.Id = pon.PonId(ponGroup.Olt.Id, oltPonIndex);
 
                                pon.Index = oltPonIndex;
                                pon.PonGroupPonIndex = ponGroupPonIndex;
 
                                pon.PonGroup = (from l in PonGroupList where l.Id == ponGroup.Id select l).SingleOrDefault();
 
                                pon.Rack = pon.PonGroup.Olt.Rack;
                                pon.Sub = pon.PonGroup.Olt.Sub;
 
                                if (nokiaOdf)
                                {
                                    pon.CardSlot = oltPonIndex / olt.NumberOfLts + 1;
                                    pon.Port = oltPonIndex % olt.NumberOfLts + 1;
                                }
                                else //if(huaweiOdf)
                                {
                                    // Huawei skips slots 9 and 10 and goes directly from 8 to 11
 
                                    slot = oltPonIndex / (olt.NumberOfPonsPerLt * olt.NumberOfLts / 16) + 1;
 
                                    if (slot > 8) slot += 2;
 
                                    if (ponGroup.Olt.NumberOfFirstSlot == 0) slot--;
 
                                    pon.CardSlot = slot;
 
                                    pon.Port = (16 * oltPonIndex % olt.NumberOfPons) / (32 / olt.NumberOfOntsInPon) / 16;
 
                                }
 
                                pon.Number = ponNumber;
                                //pon.ProposedNumber = proposedPonNumber;
                                pon.Position = pon.PonGroup.Olt.AmsName + "-" + pon.CardSlot + "-" + pon.Port;
                                pon.Name = pon.PonGroup.Symbol + "." + pon.Number;
 
#if DEBUG
                                if (pon.Name == "SBA.618")
                                {
 
                                }
#endif
 
#if DEBUG
                                // this will throw an exception if there is a duplicate pon.Id
                                if (ponIdDictionary.ContainsKey(pon.Id))
                                {
                                    throw new ArgumentOutOfRangeException(@"ponDictionary.ContainsKey(pon.Id)");
                                }
                                else ponIdDictionary[pon.Id] = pon.Name;
#endif
 
                                ponList.Add(pon);
                            }
#if DEBUG
                            /*
                            else if ((int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex] != 0 && (ponGroup.HasNewProposedPonList && (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex] == 0))
                            {
                                throw new ArgumentOutOfRangeException(@"Fault condition met: (int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex] != 0 && (!ponGroup.UsesProposedList || (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex] == 0)");
                            }
                            else if ((int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex] == 0 && (ponGroup.HasNewProposedPonList && (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex] != 0))
                            {
                                throw new ArgumentOutOfRangeException(@"Fault condition met: (int)ponGroup.UsedPonInPonGroupList[ponGroupPonIndex] == 0 && (!ponGroup.UsesProposedList || (int)ponGroup.UsedProposedPonInPonGroupList[ponGroupPonIndex] != 0)");
                            }
                            else
                            {
                            }
                            */
#endif
                            oltPonIndex++;
                        }
                        //}
                        //else throw new ArgumentOutOfRangeException(@"Condition not met: (!ponGroup.UsesProposedList || ponGroup.UsedPonInPonGroupList.Count == ponGroup.UsedProposedPonInPonGroupList.Count)");
                    }
                    //}
                    //else throw new ArgumentOutOfRangeException(@"Condition not met: ((oltPonCount == oltProposedPonCount) || oltProposedPonCount == 0) && oltPonCount % 32 == 0");
                }
 
                return ponList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Dictionary<string, string> PonNameToPonIdDictionary
        {
            get
            {
                if (ponNameToPonIdDictionary == null || ponNameToPonIdDictionary.Count == 0)
                {
                    lock (objectLock)
                    {
                        ponNameToPonIdDictionary = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
                                                    select new { p.Name, p.Id }).ToDictionary(n => n.Name, n => n.Id);
                    }
                }
 
                return ponNameToPonIdDictionary;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> PonIdToPonDictionary
        {
            get
            {
                if (ponIdToPonDictionary == null || ponIdToPonDictionary.Count == 0)
                {
                    lock (objectLock)
                    {
                        ponIdToPonDictionary = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
                                                select new { p.Id, Pon = p }).ToDictionary(n => n.Id, n => n.Pon);
                    }
                }
 
                return ponIdToPonDictionary;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Dictionary<string, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> PonNameToPonDictionary
        {
            get
            {
                if (ponNameToPonDictionary == null || ponNameToPonDictionary.Count == 0)
                {
                    lock (objectLock)
                    {
                        ponNameToPonDictionary = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
                                                  select new { p.Name, Pon = p }).ToDictionary(n => n.Name, n => n.Pon);
                    }
                }
 
                return ponNameToPonDictionary;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon PonByOltEmsNameAndSnAndPnAndOptionallyOntId(string emsName, int sn, int pn, int ontId)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon;
 
            var olt = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltByEmsName(emsName);
 
            if (olt.EmsName == "OLT-QRN-ABW-01") // ABW is all screwed up with multiple PON grouped. I will use ontId and read PON from OntList
            {
                pon = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
                       where o.Pon.PonGroup.Olt.Id == olt.Id && o.CardSlot == sn && o.Port == pn && o.InternalNumber == ontId
                       select o.Pon).SingleOrDefault();
            }
            else
            {
                pon = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
                       where p.PonGroup.Olt.Id == olt.Id && p.CardSlot == sn && p.Port == pn
                       select p).SingleOrDefault();
            }
 
            return pon;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup> PonGroupList
        {
            get
            {
                if (ponGroupList == null || ponGroupList.Count == 0)
                {
                    lock (objectLock)
                    {
                        ponGroupList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._PonGroupList;
                    }
                }
 
                return ponGroupList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup> _PonGroupList
        {
            get
            {
                int networkId, siteId, routerId, odfId, oltId, id;
                const string pattern = @"\d{1,3}\.\d{1,3}\.\d{1,3}\.0";
                Regex regex;
                Hashtable idHashtable, networkNumberHashtable;
#if DEBUG
                Hashtable gatewayIpHashtable;
#endif
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup ponGroup;
 
                regex = new Regex(pattern);
                var ponGroupList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup>(16); // 16 is max number of ponGroup in ONT
                idHashtable = new Hashtable();
                networkNumberHashtable = new Hashtable();
#if DEBUG
                gatewayIpHashtable = new Hashtable();
#endif
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("router").Elements("odf").Elements("olt").Elements("ponGroup"))
                {
                    ponGroup = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PonGroup
                    {
                        Olt = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt()
                    };
                    ponGroup.Olt.Odf = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf();
                    ponGroup.Olt.Odf.Router = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router();
                    ponGroup.Olt.Odf.Router.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Parent.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Parent.Parent.Parent.Attribute("id").Value);
                    routerId = int.Parse(x.Parent.Parent.Parent.Attribute("id").Value);
                    odfId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    oltId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = ponGroup.Olt.Odf.Router.Site.SiteId(networkId, siteId);
                    routerId = ponGroup.Olt.Odf.Router.RouterId(siteId, routerId);
                    odfId = ponGroup.Olt.Odf.OdfId(routerId, odfId);
                    oltId = ponGroup.Olt.OltId(odfId, oltId);
                    ponGroup.Id = ponGroup.PonGroupId(oltId, id);
 
                    ponGroup.Number = id;
 
                    ponGroup.Olt = (from o in OltList where o.Id == oltId select o).Single(); //.SingleOrDefault();
 
                    if (x.Attribute("symbol") != null) ponGroup.Symbol = x.Attribute("symbol").Value;
                    else ponGroup.Symbol = ponGroup.Olt.Symbol;
 
                    ponGroup.NetworkNumber = x.Attribute("networkNumber").Value;
                    // Network number must be unique and must end with *.*.*.0
                    if (networkNumberHashtable.ContainsKey(ponGroup.NetworkNumber)) throw new ArgumentException(@"Lt.NetworkNumber is not unique for LT under OLT name=" + ponGroup.Olt.Name + ". ");
                    else if (!regex.IsMatch(ponGroup.NetworkNumber)) throw new ArgumentException(@"Lt.NetworkNumber is not if format *.*.*.0 OLT name=" + ponGroup.Olt.Name + ". ");
                    else networkNumberHashtable[ponGroup.NetworkNumber] = 1;
 
 
                    ponGroup.PonListString = x.Attribute("list").Value;
                    // below: pass ponList and change "*" to "0"
                    ponGroup.UsedPonInPonGroupList = Ia.Cl.Model.Default.ConvertHyphenAndCommaSeperatedNumberStringToNumberList(ponGroup.PonListString.Replace("*", "0"));
 
                    /*
                    if (x.Attribute("proposedList") != null && x.Attribute("proposedList").Value.Length > 0)
                    {
                        ponGroup.ProposedPonListString = x.Attribute("proposedList").Value;
                        // below: pass ponList and change "*" to "0"
                        ponGroup.UsedProposedPonInPonGroupList = Ia.Cl.Model.Default.ConvertHyphenAndCommaSeperatedNumberStringToNumberList(ponGroup.ProposedPonListString.Replace("*", "0"));
                    }
                    else
                    {
                        ponGroup.ProposedPonListString = string.Empty;
                        ponGroup.UsedProposedPonInPonGroupList = new List<int>();
                    }
                    */
 
                    if (x.Attribute("gatewayIp") != null) ponGroup.GatewayIp = x.Attribute("gatewayIp").Value;
                    else if (x.Parent.Attribute("gatewayIp") != null) ponGroup.GatewayIp = x.Parent.Attribute("gatewayIp").Value;
                    else if (x.Parent.Parent.Attribute("gatewayIp") != null) ponGroup.GatewayIp = x.Parent.Parent.Attribute("gatewayIp").Value;
                    else throw new ArgumentException(@"ponGroup.GatewayIp could not be produced from XML document. ");
 
                    if (x.Attribute("mgcIp") != null) ponGroup.MgcIp = x.Attribute("mgcIp").Value;
                    else if (x.Parent.Attribute("mgcIp") != null) ponGroup.MgcIp = x.Parent.Attribute("mgcIp").Value;
                    else if (x.Parent.Parent.Attribute("mgcIp") != null) ponGroup.MgcIp = x.Parent.Parent.Attribute("mgcIp").Value;
                    else if (ponGroup.Olt.Name != "SAA-1" && (ponGroup.Olt.Name != "SDQ-1")) throw new ArgumentException(@"ponGroup.MgcIp could not be produced from XML document. ");
                    // note that MgcIp need some special handling on the PON.ONT level
 
#if DEBUG
                    // GatewayIp number must be unique
                    /*if (gatewayIpHashtable.ContainsKey(ponGroup.GatewayIp)) throw new ArgumentException(@"Lt.GatewayIp is not unique for LT under OLT name=" + ponGroup.Olt.Name + ". ");
                    else*/
                    gatewayIpHashtable[ponGroup.GatewayIp] = 1;
 
                    // Id
                    if (idHashtable.ContainsKey(ponGroup.Id)) throw new ArgumentException(@"ponGroup.Id is not unique for LT under OLT name=" + ponGroup.Olt.Name + ". ");
                    else idHashtable[ponGroup.Id] = 1;
#endif
                    ponGroupList.Add(ponGroup);
                }
 
                return ponGroupList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> OltList
        {
            get
            {
                if (oltList == null || oltList.Count == 0)
                {
                    lock (objectLock)
                    {
                        oltList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._OltList;
                    }
                }
 
                return oltList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> _OltList
        {
            get
            {
                int networkId, siteId, routerId, odfId, id;
                string fieldTypeString;
                Hashtable networkNumberHashtable;
                //Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState state;
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt olt;
 
                var oltList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt>(100);
                networkNumberHashtable = new Hashtable();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("router").Elements("odf").Elements("olt"))
                {
                    olt = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt();
                    olt.Odf = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf();
                    olt.Odf.Router = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router();
                    olt.Odf.Router.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Parent.Parent.Attribute("id").Value);
                    routerId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    odfId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = olt.Odf.Router.Site.SiteId(networkId, siteId);
                    routerId = olt.Odf.Router.RouterId(siteId, routerId);
                    odfId = olt.Odf.OdfId(routerId, odfId);
                    olt.Id = olt.OltId(odfId, id);
 
                    olt.Odf = (from o in OdfList where o.Id == odfId select o).Single(); //.SingleOrDefault();
 
                    olt.Name = x.Attribute("name").Value;
                    olt.AmsName = x.Attribute("amsName").Value;
 
                    if (x.Attribute("did") != null) olt.Did = int.Parse(x.Attribute("did").Value);
 
                    olt.Type = x.Attribute("type").Value;
 
                    /*
                    if (x.Attribute("state") != null)
                    {
                        switch (x.Attribute("state").Value)
                        {
                            case "is-nr": state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.IsNr; break;
                            case "oos-au": state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.OosAu; break;
                            case "oos-ma": state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.OosMa; break;
                            case "oos-auma": state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.OosAuma; break;
                            default: state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.Undefined; break;
                        }
                    }
                    else state = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.Undefined;
                    */
 
                    //olt.StateId = (int)state;
 
                    olt.IsSip = x.Attribute("isSip").Value == "true";
 
                    if (olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia)
                    {
                        olt.Rack = 1;
                        olt.Sub = 1;
                    }
                    else //if (olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei)
                    {
                        olt.Rack = 0;
                        olt.Sub = 0;
                    }
 
                    if (x.Attribute("gatewayIp") != null) olt.GatewayIp = x.Attribute("gatewayIp").Value;
                    else if (x.Parent.Attribute("gatewayIp") != null) olt.GatewayIp = x.Parent.Attribute("gatewayIp").Value;
                    else olt.GatewayIp = string.Empty;
 
                    if (x.Attribute("mgcIp") != null) olt.MgcIp = x.Attribute("mgcIp").Value;
                    else if (x.Parent.Attribute("mgcIp") != null) olt.MgcIp = x.Parent.Attribute("mgcIp").Value;
                    else olt.MgcIp = string.Empty;
 
                    fieldTypeString = x.Attribute("fieldType").Value;
 
                    if (!string.IsNullOrEmpty(fieldTypeString))
                    {
                        if (fieldTypeString == "green") olt.FieldType = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green;
                        else if (fieldTypeString == "brown") olt.FieldType = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown;
                        else throw new ArgumentException(@"OLT field type unrecognized. ");
                    }
                    else throw new ArgumentException(@"OLT field type invalid. ");
 
                    olt.Symbol = x.Attribute("symbol").Value;
 
                    // below: the number of possible PONs differs between Nokia OLT types and Huawei
                    if (olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia)
                    {
                        olt.NumberOfPonsPerLt = 16;
                        olt.NumberOfOntsInPon = 32;
                        olt.NumberOfFirstSlot = 1;
 
                        if (olt.Type == "7342")
                        {
                            olt.NumberOfLts = 2;
                        }
                        else if (olt.Type == "7360")
                        {
                            olt.NumberOfLts = 16;
                        }
                        else
                        {
                            throw new ArgumentException(@"Nokia olt.Type unrecognized. ");
                        }
                    }
                    else if (olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei)
                    {
                        olt.NumberOfLts = 2;
 
                        if (olt.Type == "MA5600T")
                        {
                            olt.NumberOfPonsPerLt = 128;
                            olt.NumberOfOntsInPon = 32;
                            olt.NumberOfFirstSlot = 1;
                        }
                        else if (olt.Type == "MA5600T-temp")
                        {
                            olt.NumberOfPonsPerLt = 128 * 8;
                            olt.NumberOfOntsInPon = 4;
                            olt.NumberOfFirstSlot = 1;
                        }
                        else if (olt.Type == "MA5603T")
                        {
                            olt.NumberOfPonsPerLt = 128;
                            olt.NumberOfOntsInPon = 32;
                            olt.NumberOfFirstSlot = 0;
                        }
                        else
                        {
                            throw new ArgumentException(@"Huawei olt.Type unrecognized. ");
                        }
                    }
                    else
                    {
                        throw new ArgumentException(@"olt.Odf.Vendor unrecognized. ");
                    }
 
                    olt.NumberOfPons = olt.NumberOfLts * olt.NumberOfPonsPerLt;
#if DEBUG
                    if ((olt.NumberOfPons * olt.NumberOfOntsInPon % 1024) != 0) throw new ArgumentException(@"(olt.NumberOfPons * olt.NumberOfOntsInPon % 1024) != 0");
                    if (olt.NumberOfFirstSlot != 0 && olt.NumberOfFirstSlot != 1) throw new ArgumentException(@"olt.NumberOfFirstSlot == 0 || olt.NumberOfFirstSlot == 1");
#endif
                    oltList.Add(olt);
                }
 
                return oltList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> NokiaOltList
        {
            get
            {
                lock (objectLock)
                {
                    return VendorOltList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia, 0);
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> HuaweiOltList
        {
            get
            {
                lock (objectLock)
                {
                    return VendorOltList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei, 0);
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> VendorOltList(Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor vendor, int siteId)
        {
            lock (objectLock)
            {
                List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> list;
 
                list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                        where o.Odf.Vendor == vendor && (o.Odf.Router.Site.Id == siteId || siteId == 0)
                        select o).ToList();
 
                return list;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> NokiaOltIdList()
        {
            return OltIdByVendorAndSiteIdList("No", 0);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> NokiaOltIdList(int siteId)
        {
            return OltIdByVendorAndSiteIdList("No", siteId);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> HuaweiOltIdList()
        {
            return OltIdByVendorAndSiteIdList("Hu", 0);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> HuaweiOltIdList(int siteId)
        {
            return OltIdByVendorAndSiteIdList("Hu", siteId);
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> OltIdByVendorAndSiteIdList(string vendorShortName, int siteId)
        {
            List<int> list;
 
            list = new List<int>();
 
            foreach (var olt in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList)
            {
                // siteId 0 will return all sites
 
                if (olt.Odf.Vendor.ShortName == vendorShortName && (olt.Odf.Router.Site.Id == siteId || siteId == 0))
                {
                    list.Add(olt.Id);
                }
            }
 
            return list;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> NokiaSwitchNokiaAccessOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                                where o.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
                                && o.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
                                select o.Id).ToList();
 
                    return list;
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> HuaweiSwitchNokiaAccessOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                                where o.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei
                                && o.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
                                select o.Id).ToList();
 
                    return list;
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> NokiaRouterHuaweiAccessOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    var list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                                where o.Odf.Router.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
                                && o.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei
                                select o.Id).ToList();
 
                    return list;
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt OltByEmsName(string emsName)
        {
            var olt = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                       where o.EmsName == emsName
                       select o).SingleOrDefault();
 
            return olt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt OltByDid(int did)
        {
            var olt = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                       where o.Did == did
                       select o).SingleOrDefault();
 
            return olt;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Dictionary<int, int> DidToOltIdDictionary
        {
            get
            {
                if (didToOltIdDictionary == null || didToOltIdDictionary.Count == 0)
                {
                    lock (objectLock)
                    {
                        didToOltIdDictionary = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                                                where o.Did != 0
                                                select new { o.Did, OltId = o.Id }).ToDictionary(n => n.Did, n => n.OltId);
                    }
                }
 
                return didToOltIdDictionary;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> SipOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.IsSip == true
                            select o.Id).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> GreenFieldOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green
                            select o.Id).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> GreenFieldOltList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green
                            select o).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> GreenFieldSipOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.IsSip == true && o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green
                            select o.Id).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> GreenFieldSipOltList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.IsSip == true && o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green
                            select o).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> GreenFieldOntList
        {
            get
            {
                if (greenFieldOntList == null || greenFieldOntList.Count == 0)
                {
                    lock (objectLock)
                    {
                        greenFieldOntList = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
                                             where o.Pon.PonGroup.Olt.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Green
                                             select o).ToList();
 
                    }
                }
 
                return greenFieldOntList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> BrownFieldOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown
                            select o.Id).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> BrownFieldOltList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown
                            select o).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<int> BrownFieldSipOltIdList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.IsSip == true && o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown
                            select o.Id).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Olt> BrownFieldSipOltList
        {
            get
            {
                lock (objectLock)
                {
                    return (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.IsSip == true && o.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown
                            select o).ToList();
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont> BrownFieldOntList
        {
            get
            {
                if (brownFieldOntList == null || brownFieldOntList.Count == 0)
                {
                    lock (objectLock)
                    {
                        brownFieldOntList = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OntList
                                             where o.Pon.PonGroup.Olt.FieldType == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.FieldType.Brown
                                             select o).ToList();
 
                    }
                }
 
                return brownFieldOntList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> NokiaOltAmsNameList
        {
            get
            {
                lock (objectLock)
                {
                    List<string> list;
 
                    list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
                            //&& o.StateId == (int)Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.IsNr
                            select o.AmsName).ToList();
 
                    return list;
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<string> HuaweiOltAmsNameList
        {
            get
            {
                lock (objectLock)
                {
                    List<string> list;
 
                    list = (from o in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.OltList
                            where o.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei
                            //&& o.StateId == (int)Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.BellcoreState.IsNr
                            select o.AmsName).ToList();
 
                    return list;
                }
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf> OdfList
        {
            get
            {
                if (odfList == null || odfList.Count == 0)
                {
                    lock (objectLock)
                    {
                        odfList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._OdfList;
                    }
                }
 
                return odfList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf> _OdfList
        {
            get
            {
                int networkId, siteId, routerId, id;
                string vendorShortName;
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf odf;
 
                var odfList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf>();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("router").Elements("odf"))
                {
                    odf = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Odf();
                    odf.Router = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router();
                    odf.Router.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    routerId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = odf.Router.Site.SiteId(networkId, siteId);
                    routerId = odf.Router.RouterId(siteId, routerId);
                    odf.Id = odf.OdfId(routerId, id);
 
                    odf.Name = x.Attribute("name").Value;
 
                    odf.GatewayIp = (x.Attribute("gatewayIp") != null) ? x.Attribute("gatewayIp").Value : string.Empty;
                    odf.MgcIp = (x.Attribute("mgcIp") != null) ? x.Attribute("mgcIp").Value : string.Empty;
 
                    vendorShortName = x.Attribute("vendorShortName").Value;
                    odf.Vendor = (from v in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.VendorList where v.ShortName == vendorShortName select v).Single(); //.si.SingleOrDefault();
 
                    odf.Router = (from r in RouterList where r.Id == routerId select r).Single(); //.SingleOrDefault();
 
                    odfList.Add(odf);
                }
 
                return odfList.ToList();
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam> OamList
        {
            get
            {
                if (oamList == null || oamList.Count == 0)
                {
                    lock (objectLock)
                    {
                        oamList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._OamList;
                    }
                }
 
                return oamList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam> _OamList
        {
            get
            {
                int networkId, siteId, routerId, id;
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam oam;
 
                var oamList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam>();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("router").Elements("oam"))
                {
                    oam = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Oam();
                    oam.Router = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router();
                    oam.Router.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    routerId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = oam.Router.Site.SiteId(networkId, siteId);
                    routerId = oam.Router.RouterId(siteId, routerId);
                    oam.Id = oam.OamId(routerId, id);
 
                    oam.Network = x.Attribute("network").Value;
                    oam.Gateway = x.Attribute("gateway").Value;
                    oam.Vlan = int.Parse(x.Attribute("vlan").Value);
                    oam.Vpls = int.Parse(x.Attribute("vpls").Value);
                    oam.FtpIp = x.Attribute("ftpIp").Value;
                    oam.ConfigFile = x.Attribute("configFile").Value;
 
                    oam.Router = (from r in RouterList where r.Id == routerId select r).Single(); //.SingleOrDefault();
 
                    oamList.Add(oam);
                }
 
                return oamList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor SwitchVendorByService(string service)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor switchVendor;
 
            if (int.TryParse(service, out int i))
            {
                switchVendor = (from r in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.RouterList
                                where r.DomainList.Any(u => service.StartsWith(u.ToString()))
                                select r.Vendor).FirstOrDefault(); //.SingleOrDefault();
 
                if (switchVendor == null) switchVendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
            }
            else switchVendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
            return switchVendor;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> SwitchVendorListByServiceList(List<string> serviceList)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor switchVendor;
            var switchVendorList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor>();
 
            foreach (var service in serviceList)
            {
                if (int.TryParse(service, out int i))
                {
                    switchVendor = (from r in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.RouterList
                                    where r.DomainList.Any(u => service.StartsWith(u.ToString()))
                                    select r.Vendor).FirstOrDefault(); //.SingleOrDefault();
 
                    if (switchVendor == null) switchVendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
                }
                else switchVendor = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Undefined;
 
                switchVendorList.Add(switchVendor);
            }
 
            return switchVendorList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn PstnFromService(int number)
        {
            return PstnFromService(number.ToString());
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn PstnFromService(string service)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn;
 
            if (int.TryParse(service, out int i))
            {
                pstn = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList
                        where p.DomainList.Any(u => service.StartsWith(u.ToString()))
                        select p).SingleOrDefault();
            }
            else pstn = null;
 
            return pstn;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> PstnThatUsesNpServerList
        {
            get
            {
                var list = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList
                            where p.UsesNpServer == true
                            select p).ToList();
 
                return list;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> PstnList
        {
            get
            {
                if (pstnList == null || pstnList.Count == 0)
                {
                    lock (objectLock)
                    {
                        var networkId = 1; // <network id="1" name="Optical Fiber Network">
 
                        pstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._PstnList(networkId);
                    }
                }
 
                return pstnList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> LegacyPstnList
        {
            get
            {
                if (legacyPstnList == null || legacyPstnList.Count == 0)
                {
                    lock (objectLock)
                    {
                        var networkId = 2; // <network id="2" name="Legacy">
 
                        legacyPstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._PstnList(networkId);
                    }
                }
 
                return legacyPstnList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> OfnAndLegacyPstnList
        {
            get
            {
                var pstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList;
                var legacyPstnList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.LegacyPstnList;
 
                var list = pstnList.Union(legacyPstnList).ToList();
 
                return list;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn LegacyPstnFromService(int number)
        {
            return LegacyPstnFromService(number.ToString());
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn LegacyPstnFromService(string service)
        {
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn;
 
            if (int.TryParse(service, out int i))
            {
                pstn = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.LegacyPstnList
                        where p.DomainList.Any(u => service.StartsWith(u.ToString()))
                        select p).SingleOrDefault();
            }
            else pstn = null;
 
            return pstn;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn> _PstnList(int networkId)
        {
            int siteId, id;
            string pstnExchangeTypeString, usesNpServerString;
#if DEBUG
            //Dictionary<int, int> domainDictionary;
#endif
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn pstn;
 
#if DEBUG
            //domainDictionary = new Dictionary<int, int>(100);
#endif
            var pstnList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn>();
 
            var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                   where n.Attribute("id").Value == networkId.ToString()
                                   select n).Single();
 
            foreach (XElement x in networkXElement.Elements("site").Elements("pstn"))
            {
                pstn = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn();
                pstn.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                networkId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                siteId = int.Parse(x.Parent.Attribute("id").Value);
                id = int.Parse(x.Attribute("id").Value);
 
                siteId = pstn.Site.SiteId(networkId, siteId);
                pstn.Id = pstn.PstnId(siteId, id);
                pstn.Name = x.Attribute("name").Value;
                pstn.ArabicName = x.Attribute("arabicName").Value;
 
                //if (x.Attribute("ip") != null) pstn.Ip = x.Attribute("ip").Value;
                //else pstn.Ip = string.Empty;
 
                pstn.DomainListString = x.Attribute("domainList").Value;
 
                pstn.DomainList = Ia.Cl.Model.Default.CommaSeperatedNumberStringToNumberList(pstn.DomainListString);
 
#if DEBUG
                /*
                foreach (int i in pstn.DomainList)
                {
                    // this will throw an exception if there are similar domains in pstns
                    if (domainDictionary.ContainsKey(i))
                    {
                        throw new ArgumentOutOfRangeException(@"domainDictionary.ContainsKey(" + i + ")");
                    }
                    else domainDictionary[i] = 1;
                }
                */
#endif
 
                pstnExchangeTypeString = x.Attribute("type").Value;
 
                if (pstnExchangeTypeString == "EWSD") pstn.PstnExchangeType = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType.SiemensEwsd;
                else if (pstnExchangeTypeString == "AXE") pstn.PstnExchangeType = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType.EricssonAxe;
                else if (pstnExchangeTypeString == "MRD") pstn.PstnExchangeType = Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.PstnExchangeType.NortelMeridian;
#if DEBUG
                else throw new ArgumentOutOfRangeException(@"Unknown PSTN exchange type: " + pstnExchangeTypeString);
#endif
                usesNpServerString = x.Attribute("usesNpServer") != null ? x.Attribute("usesNpServer").Value : "false";
                pstn.UsesNpServer = usesNpServerString == "true";
 
                if (networkId == 1) pstn.Site = (from s in SiteList where s.Id == siteId select s).Single(); // <network id="1" name="Optical Fiber Network">
                else /*if(networkId == 2)*/ pstn.Site = (from s in LegacySiteList where s.Id == siteId select s).Single(); // <network id="2" name="Legacy">
 
                pstnList.Add(pstn);
            }
 
            return pstnList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pstn PstnFromName(string name)
        {
            var pstn = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PstnList where p.Name == name select p).Single();
 
            return pstn;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan> MsanList
        {
            get
            {
                if (msanList == null || msanList.Count == 0)
                {
                    lock (objectLock)
                    {
                        msanList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._MsanList;
                    }
                }
 
                return msanList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan> _MsanList
        {
            get
            {
                int networkId, siteId, id;
                //string usesNpServerString;
#if DEBUG
                //Dictionary<int, int> domainDictionary;
#endif
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan msan;
 
#if DEBUG
                //domainDictionary = new Dictionary<int, int>(100);
#endif
                var msanList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan>();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("msan"))
                {
                    msan = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan();
                    msan.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = msan.Site.SiteId(networkId, siteId);
                    msan.Id = msan.MsanId(siteId, id);
                    msan.NameSymbol = x.Attribute("nameSymbol").Value;
 
                    msan.DomainListString = x.Attribute("domainList").Value;
 
                    msan.DomainList = Ia.Cl.Model.Default.CommaSeperatedNumberStringToNumberList(msan.DomainListString);
 
                    //usesNpServerString = x.Attribute("usesNpServer").Value;
                    msan.UsesNpServer = false; // usesNpServerString == "true";
 
                    msan.Site = (from s in SiteList where s.Id == siteId select s).Single(); //.SingleOrDefault();
 
#if DEBUG
                    /*
                     
                    // You might have and MSAN on a site but the equivalent domains in another site
                    if (msan.DomainList != null)
                    {
                        foreach (var s in msan.DomainList)
                        {
                            if (!msan.Site.DomainList.Contains(s))
                            {
                                throw new ArgumentOutOfRangeException(@"msan.Site.DomainList does not contain " + s + ".");
                            }
                        }
                    }
                    */
 
 
                    /*
                    foreach (int i in msan.DomainList)
                    {
                        // this will throw an exception if there are similar domains in pstns
                        if (domainDictionary.ContainsKey(i))
                        {
                            throw new ArgumentOutOfRangeException(@"domainDictionary.ContainsKey(" + i + ")");
                        }
                        else domainDictionary[i] = 1;
                    }
                    */
#endif
 
                    msanList.Add(msan);
                }
 
                return msanList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan MsanFromNameSymbol(string nameSymbol)
        {
            var msanList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.MsanList;
 
            var msan = (from m in msanList
                        where m.NameSymbol == nameSymbol
                        select m).SingleOrDefault();
 
            return msan;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan MsanFromSiteName(string siteName)
        {
            var siteList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.SiteList;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Msan msan;
 
            var site = (from s in siteList
                        where s.Name == siteName
                        select s).SingleOrDefault();
 
            msan = (site != null && site.Msans.Count != 0) ? site.Msans.FirstOrDefault() : null;
 
            return msan;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX> SoftXList
        {
            get
            {
                if (softXList == null || softXList.Count == 0)
                {
                    lock (objectLock)
                    {
                        softXList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._SoftXList;
                    }
                }
 
                return softXList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX> _SoftXList
        {
            get
            {
                int networkId, siteId, id;
#if DEBUG
                //Dictionary<int, int> domainDictionary;
#endif
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX softX;
 
#if DEBUG
                //domainDictionary = new Dictionary<int, int>(100);
#endif
                var softXList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX>();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("softx"))
                {
                    softX = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.SoftX();
                    softX.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = softX.Site.SiteId(networkId, siteId);
                    softX.Id = softX.SoftXId(siteId, id);
 
                    softX.DomainListString = x.Attribute("domainList").Value;
 
                    softX.DomainList = Ia.Cl.Model.Default.CommaSeperatedNumberStringToNumberList(softX.DomainListString);
 
                    softX.Site = (from s in SiteList where s.Id == siteId select s).Single(); //.SingleOrDefault();
 
#if DEBUG
                    /*
                    if (softX.DomainList != null)
                    {
                        foreach (var s in softX.DomainList)
                        {
                            if (!softX.Site.DomainList.Contains(s))
                            {
                                throw new ArgumentOutOfRangeException(@"softX.Site.DomainList does not contain " + s + ".");
                            }
                        }
                    }
                    */
 
                    /*
                    foreach (int i in softX.DomainList)
                    {
                        // this will throw an exception if there are similar domains in sps
                        if (domainDictionary.ContainsKey(i))
                        {
                            throw new ArgumentOutOfRangeException(@"domainDictionary.ContainsKey(" + i + ")");
                        }
                        else domainDictionary[i] = 1;
                    }
                    */
#endif
 
                    softXList.Add(softX);
                }
 
                return softXList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router> RouterList
        {
            get
            {
                if (routerList == null || routerList.Count == 0)
                {
                    lock (objectLock)
                    {
                        routerList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._RouterList;
                    }
                }
 
                return routerList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router> _RouterList
        {
            get
            {
                int networkId, siteId, id;
                string vendorShortName;
#if DEBUG
                //Dictionary<int, int> domainDictionary;
#endif
                Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router router;
 
#if DEBUG
                //domainDictionary = new Dictionary<int, int>(100);
#endif
                var routerList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router>();
 
                var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                       where n.Attribute("id").Value == "1" // <network id="1" name="Optical Fiber Network">
                                       select n).Single();
 
                foreach (XElement x in networkXElement.Elements("site").Elements("router"))
                {
                    router = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Router();
                    router.Site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
 
                    networkId = int.Parse(x.Parent.Parent.Attribute("id").Value);
                    siteId = int.Parse(x.Parent.Attribute("id").Value);
                    id = int.Parse(x.Attribute("id").Value);
 
                    siteId = router.Site.SiteId(networkId, siteId);
                    router.Id = router.RouterId(siteId, id);
                    router.Name = x.Attribute("name").Value;
                    router.Type = x.Attribute("type").Value;
 
                    router.DomainListString = x.Attribute("domainList").Value;
 
                    router.DomainList = Ia.Cl.Model.Default.CommaSeperatedNumberStringToNumberList(router.DomainListString);
 
#if DEBUG
                    /*
                    foreach (int i in router.DomainList)
                    {
                        // this will throw an exception if there are similar domains in routers
                        if (domainDictionary.ContainsKey(i))
                        {
                            throw new ArgumentOutOfRangeException(@"domainDictionary.ContainsKey(" + i + ")");
                        }
                        else domainDictionary[i] = 1;
                    }
                    */
#endif
 
                    vendorShortName = x.Attribute("vendorShortName").Value;
                    router.Vendor = (from v in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.VendorList where v.ShortName == vendorShortName select v).Single(); //.s.SingleOrDefault();
 
                    router.Site = (from s in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.SiteList where s.Id == siteId select s).Single(); //.SingleOrDefault();
 
                    routerList.Add(router);
                }
 
                return routerList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> SiteList
        {
            get
            {
                if (siteList == null || siteList.Count == 0)
                {
                    lock (objectLock)
                    {
                        var networkId = 1; // <network id="1" name="Optical Fiber Network">
 
                        siteList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._SiteList(networkId);
                    }
                }
 
                return siteList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> LegacySiteList
        {
            get
            {
                if (legacySiteList == null || legacySiteList.Count == 0)
                {
                    lock (objectLock)
                    {
                        var networkId = 2; // <network id="2" name="Legacy">
 
                        legacySiteList = Ia.Ngn.Cl.Model.Data.NetworkDesignDocument._SiteList(networkId);
                    }
                }
 
                return legacySiteList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site> _SiteList(int networkId)
        {
            int id;
            Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site site;
 
            var siteList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site>();
 
            var networkXElement = (from n in XDocument.Element("networkDesignDocument").Elements("network")
                                   where n.Attribute("id").Value == networkId.ToString()
                                   select n).Single();
 
            foreach (XElement x in networkXElement.Elements("site"))
            {
                site = new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site();
                networkId = int.Parse(x.Parent.Attribute("id").Value);
                id = int.Parse(x.Attribute("id").Value);
 
                site.Id = site.SiteId(networkId, id);
                site.Name = x.Attribute("name").Value;
                site.ArabicName = x.Attribute("arabicName").Value;
 
                site.Network = (from n in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.NetworkList
                                where n.Id == networkId
                                select n).Single();
 
                siteList.Add(site);
            }
 
            return siteList;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Site SiteFromName(string name)
        {
            var site = (from s in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.SiteList where s.Name == name select s).Single();
 
            return site;
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Network> NetworkList
        {
            get
            {
                if (networkList == null || networkList.Count == 0)
                {
                    lock (objectLock)
                    {
                        networkList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Network>
                        {
                            new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Network(1, "Optical Fiber Network"),
                            new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Network(2, "Legacy")
                        };
                    }
                }
 
                return networkList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor> VendorList
        {
            get
            {
                if (vendorList == null || vendorList.Count == 0)
                {
                    lock (objectLock)
                    {
                        vendorList = new List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor>
                    {
                        new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor(0, "Undefined", "Un", "غير معرف", @"~\image\undefined.png"),
                        new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor(1, "Nokia", "No", "نوكيا", @"~\image\nokia-icon.png"),
                        new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor(2, "Huawei", "Hu", "هواوي", @"~\image\huawei-icon.png"),
                        new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor(3, "Ericsson", "Er", "إريكسون", @"~\image\ericsson-icon.png"),
                        new Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor(4, "Siemens", "Si", "سيمينس", @"~\image\siemens-icon.png")
                    };
                    }
                }
 
                return vendorList;
            }
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string AmsNameFromOltId(int oltId)
        {
            var amsName = (from o in OltList
                           where o.Id == oltId
                           select o.AmsName).FirstOrDefault();
 
            return amsName;
        }
 
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        ///
        /// </summary>
        public static string XDocument2()
        {
            return xDocument.ToString();
        }
 
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
 
        /// <summary>
        /// 
        /// How to embed and access resources by using Visual C# http://support.microsoft.com/kb/319292/en-us
        /// 
        /// 1. Change the "Build Action" property of your XML file from "Content" to "Embedded Resource".
        /// 2. Add "using System.Reflection".
        /// 3. Manifest resource stream will start with the project namespace, the location of XML file.
        /// 
        /// </summary>
        private static XDocument XDocument
        {
            get
            {
                if (xDocument == null)
                {
                    lock (objectLock)
                    {
                        Assembly _assembly;
                        StreamReader streamReader;
 
                        _assembly = Assembly.GetExecutingAssembly();
                        streamReader = new StreamReader(_assembly.GetManifestResourceStream("Ia.Ngn.Cl.model.data.network-design-document.xml"));
 
                        try
                        {
                            if (streamReader.Peek() != -1) xDocument = System.Xml.Linq.XDocument.Load(streamReader);
                        }
                        catch (Exception)
                        {
                        }
                        finally
                        {
                        }
                    }
                }
 
                return xDocument;
            }
        }
    }
 
    ////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////    
}