)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Skip Navigation Links

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

Optical Fiber Network's Operations Support System Management Intranet (OFN OSS) support class for Nokia's Optical Fiber Network (OFN) business model.

    1: using System;
    2: using System.Collections.Generic;
    3: using System.Configuration;
    4: using System.Linq;
    5: using System.Text;
    6: using static Ia.Ngn.Cl.Model.Business.NetworkDesignDocument;
    7:  
    8: namespace Ia.Ngn.Cl.Model.Business.Nokia
    9: {
   10:     ////////////////////////////////////////////////////////////////////////////
   11:  
   12:     /// <summary publish="true">
   13:     /// Optical Fiber Network's Operations Support System Management Intranet (OFN OSS) support class for Nokia's Optical Fiber Network (OFN) business model.
   14:     /// </summary>
   15:     /// 
   16:     /// <value>
   17:     ///   <appSettings>
   18:     ///     <add key="sdcServerHost" value="https://*" />
   19:     ///     <add key="sdcServerPort" value="*" />
   20:     ///     <add key="sdcServerServiceUrl" value="*" />
   21:     ///     <add key="sdcServerUser" value="*" />
   22:     ///     <add key="sdcServerUserPassword" value="*" />
   23:     ///   </appSettings>
   24:     /// </value>
   25:     /// 
   26:     /// <remarks> 
   27:     /// Copyright © 2018-2022 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   28:     ///
   29:     /// 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
   30:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   31:     ///
   32:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   33:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   34:     /// 
   35:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   36:     /// 
   37:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   38:     /// </remarks> 
   39:     public class Sdc
   40:     {
   41:         private static List<string> ponNameList;
   42:  
   43:         private static List<Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon> ponList;
   44:  
   45:         /// <summary/>
   46:         public static string BaseAddress { get { return ConfigurationManager.AppSettings["sdcServerHost"].ToString() + ":" + ConfigurationManager.AppSettings["sdcServerPort"].ToString(); } }
   47:         /// <summary/>
   48:         public static string ServiceUrl { get { return ConfigurationManager.AppSettings["sdcServerServiceUrl"].ToString(); } }
   49:         /// <summary/>
   50:         public static string UserName { get { return ConfigurationManager.AppSettings["sdcServerUser"].ToString(); } }
   51:         /// <summary/>
   52:         public static string Password { get { return ConfigurationManager.AppSettings["sdcServerUserPassword"].ToString(); } }
   53:  
   54:         public enum Transaction { Receive, Transmit }
   55:  
   56:         /// <summary/>
   57:         public static List<TimeSpan> ScaleList
   58:         {
   59:             get
   60:             {
   61:                 return new List<TimeSpan> { TimeSpan.FromHours(1), TimeSpan.FromDays(1), TimeSpan.FromDays(7), TimeSpan.FromDays(30), TimeSpan.FromDays(365) };
   62:             }
   63:         }
   64:  
   65:         ////////////////////////////////////////////////////////////////////////////
   66:  
   67:         /// <summary>
   68:         ///
   69:         /// </summary>
   70:         public Sdc()
   71:         {
   72:         }
   73:  
   74:         ////////////////////////////////////////////////////////////////////////////
   75:  
   76:         /// <summary>
   77:         /// 
   78:         /// </summary>
   79:         public class TransactionTimestampValue
   80:         {
   81:             /// <summary/>           
   82:             public Transaction Transaction { get; set; }
   83:  
   84:             /// <summary/>           
   85:             public DateTime Timestamp { get; set; }
   86:  
   87:             /// <summary/>           
   88:             public long Value { get; set; }
   89:  
   90:             ////////////////////////////////////////////////////////////////////////////
   91:  
   92:             /// <summary>
   93:             ///
   94:             /// </summary>
   95:             public TransactionTimestampValue(Transaction transaction, DateTime timestamp, long value)
   96:             {
   97:                 this.Transaction = transaction;
   98:  
   99:                 this.Timestamp = timestamp;
  100:  
  101:                 this.Value = value;
  102:             }
  103:  
  104:             ////////////////////////////////////////////////////////////////////////////
  105:  
  106:             /// <summary>
  107:             ///
  108:             /// </summary>
  109:             public override string ToString()
  110:             {
  111:                 return this.Transaction.ToString() + ": " + this.Timestamp + ": " + this.Value;
  112:             }
  113:  
  114:             ////////////////////////////////////////////////////////////////////////////
  115:         }
  116:  
  117:         ////////////////////////////////////////////////////////////////////////////
  118:  
  119:         /// <summary>
  120:         /// Response of Nokia SDC server
  121:         /// </summary>
  122:         public class Response
  123:         {
  124:             public string Author { get; set; }
  125:  
  126:             /// <summary/>
  127:             public string Version { get; set; }
  128:  
  129:             /// <summary/>
  130:             public string Tmf854Version { get; set; }
  131:  
  132:             /// <summary/>
  133:             public string ActivityName { get; set; }
  134:  
  135:             /// <summary/>
  136:             public string MessageName { get; set; }
  137:  
  138:             /// <summary/>
  139:             public string MessageType { get; set; }
  140:  
  141:             /// <summary/>
  142:             public string SenderUri { get; set; }
  143:  
  144:             /// <summary/>
  145:             public string DestinationUri { get; set; }
  146:  
  147:             /// <summary/>
  148:             public string CommunicationPattern { get; set; }
  149:  
  150:             /// <summary/>
  151:             public string CommunicationStyle { get; set; }
  152:  
  153:             /// <summary/>
  154:             public string ActivityStatus { get; set; }
  155:  
  156:             /// <summary/>
  157:             public DateTime Timestamp { get; set; }
  158:  
  159:             /// <summary/>
  160:             public string BodyText { get; set; }
  161:  
  162:             /// <summary/>
  163:             public Dictionary<string, string> ParameterDictionary;
  164:  
  165:             /// <summary/>
  166:             public bool IsSuccessfull { get { return ReturnCode == Ia.Ngn.Cl.Model.Client.Nokia.Sdc.ResultCode.Successful; } }
  167:  
  168:             /// <summary/>
  169:             public Ia.Ngn.Cl.Model.Client.Nokia.Sdc.ResultCode ReturnCode { get; set; }
  170:  
  171:             /// <summary/>
  172:             public Response() { }
  173:         }
  174:  
  175:         ////////////////////////////////////////////////////////////////////////////
  176:  
  177:         /// <summary>
  178:         ///
  179:         /// </summary>
  180:         public static void EnableSdcPerformanceMonitoringDataOfAllPons(Ia.Ngn.Cl.Model.Client.Nokia.Sdc sdc, out Ia.Cl.Model.Result result)
  181:         {
  182:             StringBuilder sb;
  183:  
  184:             result = new Ia.Cl.Model.Result();
  185:  
  186:             if (ponList == null) ponList = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
  187:                                             where p.PonGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
  188:                                             select p).ToList();
  189:  
  190:             sb = new StringBuilder();
  191:  
  192:             foreach (var pon in ponList)
  193:             {
  194:                 Ia.Ngn.Cl.Model.Business.Nokia.Sdc.EnableSdcPerformanceMonitoringDataForPon(sdc, pon, out result);
  195:  
  196:                 result.AddResult(result);
  197:  
  198:                 sb.AppendLine(result.Message);
  199:             }
  200:         }
  201:  
  202:         ////////////////////////////////////////////////////////////////////////////
  203:  
  204:         /// <summary>
  205:         ///
  206:         /// </summary>
  207:         public static void EnableSdcPerformanceMonitoringDataForPon(Ia.Ngn.Cl.Model.Client.Nokia.Sdc sdc, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon, out Ia.Cl.Model.Result result)
  208:         {
  209:             string s;
  210:  
  211:             result = new Ia.Cl.Model.Result();
  212:  
  213:             sdc.EnablePerformanceMonitoringDataOverPon(pon, out Cl.Model.Business.Nokia.Sdc.Response response);
  214:  
  215:             s = response.Timestamp + ": " + response.ActivityName + ": " + response.ActivityStatus;
  216:             s += "\r\n";
  217:  
  218:             if (response != null && response.ParameterDictionary != null)
  219:             {
  220:                 if (response.ParameterDictionary.Count > 0)
  221:                 {
  222:                     foreach (KeyValuePair<string, string> kvp in response.ParameterDictionary)
  223:                     {
  224:                         s += kvp.Key + ": " + kvp.Value + "\r\n";
  225:                     }
  226:                 }
  227:             }
  228:  
  229:             if (response.IsSuccessfull) result.AddSuccess(s);
  230:             else result.AddError(s);
  231:         }
  232:  
  233:         ////////////////////////////////////////////////////////////////////////////
  234:  
  235:         /// <summary>
  236:         ///
  237:         /// </summary>
  238:         public static Ia.Cl.Model.Result ReadPerformanceMonitoringDataOfEnabledPon(Ia.Ngn.Cl.Model.Client.Nokia.Sdc sdc, Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Pon pon)
  239:         {
  240:             var result = new Ia.Cl.Model.Result();
  241:  
  242:             var response = sdc.GetPerformanceMonitoringDataOverPon(pon);
  243:  
  244:             var text = string.Empty;
  245:  
  246:             if (response.IsSuccessfull)
  247:             {
  248:                 // Tx
  249:                 if (response.ParameterDictionary.ContainsKey("pmParameterName0"))
  250:                 {
  251:                     var gponOltSidePonUtilTxPmIntervalTotalBytesPmParameterName = response.ParameterDictionary["pmParameterName0"];
  252:  
  253:                     if (response.ParameterDictionary.ContainsKey("pmParameterValue0"))
  254:                     {
  255:                         var gponOltSidePonUtilTxPmIntervalTotalBytesPmParameterValue = response.ParameterDictionary["pmParameterValue0"];
  256:  
  257:                         if (gponOltSidePonUtilTxPmIntervalTotalBytesPmParameterValue.Length > 0)
  258:                         {
  259:                             var list = gponOltSidePonUtilTxPmIntervalTotalBytesPmParameterValue.Split(',');
  260:  
  261:                             if (list.Length > 0)
  262:                             {
  263:                                 var valueList = new List<long>();
  264:  
  265:                                 foreach (var s in list)
  266:                                 {
  267:                                     if (long.TryParse(s, out long l)) valueList.Add(l);
  268:                                     else text += pon.Name + ": transmit: " + response.Timestamp + ": Error: can't parse s: " + s;
  269:                                 }
  270:  
  271:                                 Ia.Ngn.Cl.Model.Data.Nokia.Sdc.SaveTransactionTimestampValueListOfPon(pon, Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Transaction.Transmit, response.Timestamp, valueList);
  272:  
  273:                                 text += pon.Name + ": transmit: " + response.Timestamp + ": " + string.Join(",", valueList);
  274:                             }
  275:                             else
  276:                             {
  277:                                 text += pon.Name + ": transmit: " + response.Timestamp + ": Error: list is empty";
  278:                             }
  279:                         }
  280:                         else
  281:                         {
  282:                             text += pon.Name + ": transmit: " + response.Timestamp + ": Error: gponOltSidePonUtilTxPmIntervalTotalBytesPmParameterValue is empty";
  283:                         }
  284:  
  285:                         result.AddSuccess(text);
  286:                     }
  287:                     else
  288:                     {
  289:                         text += pon.Name + ": transmit: " + response.Timestamp + ": Error: response.ParameterDictionary does not contain key pmParameterValue0";
  290:  
  291:                         result.AddError(text);
  292:                     }
  293:                 }
  294:                 else
  295:                 {
  296:                     text += pon.Name + ": transmit: " + response.Timestamp + ": Error: response.ParameterDictionary does not contain key pmParameterName0";
  297:  
  298:                     result.AddError(text);
  299:                 }
  300:  
  301:  
  302:                 text = string.Empty;
  303:  
  304:                 // Rx
  305:                 if (response.ParameterDictionary.ContainsKey("pmParameterName1"))
  306:                 {
  307:                     var gponOltSidePonUtilRxPmIntervalTotalBytesPmParameterName = response.ParameterDictionary["pmParameterName1"];
  308:  
  309:                     if (response.ParameterDictionary.ContainsKey("pmParameterValue1"))
  310:                     {
  311:                         var gponOltSidePonUtilRxPmIntervalTotalBytesPmParameterValue = response.ParameterDictionary["pmParameterValue1"];
  312:  
  313:                         if (gponOltSidePonUtilRxPmIntervalTotalBytesPmParameterValue.Length > 0)
  314:                         {
  315:                             var list = gponOltSidePonUtilRxPmIntervalTotalBytesPmParameterValue.Split(',');
  316:  
  317:                             if (list.Length > 0)
  318:                             {
  319:                                 var valueList = new List<long>();
  320:  
  321:                                 foreach (var s in list)
  322:                                 {
  323:                                     if (long.TryParse(s, out long l)) valueList.Add(l);
  324:                                     else text += pon.Name + ": receive: " + response.Timestamp + ": Error: can't parse s: " + s;
  325:                                 }
  326:  
  327:                                 Ia.Ngn.Cl.Model.Data.Nokia.Sdc.SaveTransactionTimestampValueListOfPon(pon, Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Transaction.Receive, response.Timestamp, valueList);
  328:  
  329:                                 text += pon.Name + ": receive: " + response.Timestamp + ": " + string.Join(",", valueList);
  330:                             }
  331:                             else
  332:                             {
  333:                                 text += pon.Name + ": receive: " + response.Timestamp + ": Error: list is empty";
  334:                             }
  335:                         }
  336:                         else
  337:                         {
  338:                             text += pon.Name + ": receive: " + response.Timestamp + ": Error: gponOltSidePonUtilRxPmIntervalTotalBytesPmParameterValue is empty";
  339:                         }
  340:  
  341:                         result.AddSuccess(text);
  342:                     }
  343:                     else
  344:                     {
  345:                         text += pon.Name + ": receive: " + response.Timestamp + ": Error: response.ParameterDictionary does not contain key pmParameterValue1";
  346:  
  347:                         result.AddError(text);
  348:                     }
  349:                 }
  350:                 else
  351:                 {
  352:                     text += pon.Name + ": receive: " + response.Timestamp + ": Error: response.ParameterDictionary does not contain key pmParameterName1";
  353:  
  354:                     result.AddError(text);
  355:                 }
  356:             }
  357:             else result.AddError(text);
  358:  
  359:             return result;
  360:         }
  361:  
  362:         ////////////////////////////////////////////////////////////////////////////
  363:  
  364:         /// <summary>
  365:         ///
  366:         /// </summary>
  367:         public static List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue> AdjustTransactionTimestampHourlyValueList(Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Transaction transaction, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue> timestampValueList)
  368:         {
  369:             long l;
  370:             List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue> adjustedTimestampValueList;
  371:  
  372:             adjustedTimestampValueList = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue>();
  373:  
  374:             //previous = 0;
  375:  
  376:             foreach (var timestampValue in timestampValueList)
  377:             {
  378:                 if (timestampValue.Transaction == transaction)
  379:                 {
  380:                     l = ConvertHourlyByteCountToMegaBitsPerSecond(timestampValue.Value);
  381:  
  382:                     adjustedTimestampValueList.Add(new Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue(transaction, timestampValue.Timestamp, l));
  383:                 }
  384:             }
  385:  
  386:             return adjustedTimestampValueList;
  387:         }
  388:  
  389:         ////////////////////////////////////////////////////////////////////////////
  390:  
  391:         /// <summary>
  392:         ///
  393:         /// </summary>
  394:         public static long ConvertHourlyByteCountToMegaBitsPerSecond(long l)
  395:         {
  396:             // from Nokia support:.. these are byte counters and five minute interval means that you will have to divide the value with 300 to get bytes per second.
  397:             // ... one byte is eight bits, thus, 10 MB/s = 80 Mb/s.
  398:             // I say: to get the hourly *rate* in Mb/s I will need to divide by 3600 (seconds in an hour)
  399:  
  400:             return l / 3600 * 8 / 1000000;
  401:         }
  402:  
  403:         ////////////////////////////////////////////////////////////////////////////
  404:  
  405:         /// <summary>
  406:         ///
  407:         /// </summary>
  408:         public static void ReadPerformanceMonitoringDataOfEnabledPon(Ia.Ngn.Cl.Model.Client.Nokia.Sdc sdc, out Ia.Cl.Model.Result result)
  409:         {
  410:             if (ponList == null)
  411:             {
  412:                 ponList = (from p in Ia.Ngn.Cl.Model.Data.NetworkDesignDocument.PonList
  413:                            where p.PonGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia
  414:                            select p).ToList();
  415:             }
  416:  
  417:             var pon = ponList.Next();
  418:  
  419:             result = Ia.Ngn.Cl.Model.Business.Nokia.Sdc.ReadPerformanceMonitoringDataOfEnabledPon(sdc, pon);
  420:         }
  421:  
  422:         /*
  423:         ////////////////////////////////////////////////////////////////////////////
  424: 
  425:         /// <summary>
  426:         ///
  427:         /// </summary>
  428:         public static List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.PonNameTimestampValue> AdjusteStatisticDistributionAndCountAndAverageAccordingToTimeScaleToStatisticsListToMakeMoreResonableStorageList(List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.PonNameTimestampValue> statisticList)
  429:         {
  430:             //int i, numberOfSamplesPerTimeScale;
  431:             //TimeSpan timeSpan;
  432:             //DateTime startTime, endTime;
  433:             List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.PonNameTimestampValue> oldList, adjustedStatisticsList;
  434: 
  435:             /*
  436:             Dictionary<TimeSpan, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>> timeSpanToStatisticListDictionary;
  437:             Dictionary<TimeSpan, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>> timeScaleToStatisticsListDictionary;
  438: 
  439:             numberOfSamplesPerTimeScale = 100;
  440: 
  441:             timeScaleToStatisticsListDictionary = new Dictionary<TimeSpan, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>>();
  442: 
  443:             timeSpanToStatisticListDictionary = new Dictionary<TimeSpan, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>>();
  444:             */
  445:         //adjustedStatisticsList = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.PonNameTimestampValue>();
  446:  
  447:         /*
  448:         oldList = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>();
  449: 
  450:         foreach (var scale in Ia.Ngn.Cl.Model.Business.Nokia.Sdc.ScaleList.OrderBy(u => u.TotalSeconds))
  451:         {
  452:             timeScaleToStatisticsListDictionary[scale] = FilterAccordingToScaleTimeSpan(scale, statisticList).Except(oldList).ToList();
  453: 
  454:             oldList.AddRange(timeScaleToStatisticsListDictionary[scale]);
  455:         }
  456: 
  457: 
  458:         foreach (var timeScaleToStatisticsList in timeScaleToStatisticsListDictionary.OrderBy(u => u.Key.TotalSeconds))
  459:         {
  460:             timeSpan = new TimeSpan(timeScaleToStatisticsList.Key.Ticks / numberOfSamplesPerTimeScale);
  461: 
  462:             startTime = DateTime.UtcNow.AddHours(3) - timeScaleToStatisticsList.Key;
  463:             endTime = startTime + timeSpan;
  464: 
  465:             foreach (var statistic in timeScaleToStatisticsList.Value)
  466:             {
  467:                 for (i = 0; i < numberOfSamplesPerTimeScale; i++)
  468:                 {
  469:                     if (statistic.Timestamp >= startTime && statistic.Timestamp < endTime)
  470:                     {
  471:                         if (timeSpanToStatisticListDictionary.ContainsKey(timeSpan))
  472:                         {
  473:                             timeSpanToStatisticListDictionary[timeSpan].Add(statistic);
  474:                         }
  475:                         else
  476:                         {
  477:                             timeSpanToStatisticListDictionary[timeSpan] = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>();
  478: 
  479:                             timeSpanToStatisticListDictionary[timeSpan].Add(statistic);
  480:                         }
  481: 
  482:                         break;
  483:                     }
  484: 
  485:                     startTime = endTime;
  486:                     endTime = startTime + timeSpan;
  487:                 }
  488:             }
  489: 
  490:             statisticList = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>();
  491: 
  492:             foreach (KeyValuePair<TimeSpan, List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic>> timeSpanToStatisticList in timeSpanToStatisticListDictionary)
  493:             {
  494:                 if (timeScaleToStatisticsList.Value.Count > 0)
  495:                 {
  496:                     statisticList.Add(new Ia.Ngn.Cl.Model.Business.Nokia.Sdc.Statistic(timeScaleToStatisticsList.Value[0].Pon, startTime, (long)timeSpanToStatisticList.Value.Average(u => u.Count)));
  497:                 }
  498:             }
  499: 
  500:             adjustedStatisticsList.AddRange(statisticList);
  501:         }
  502:         * /
  503: 
  504:         foreach (var v in statisticList)
  505:         {
  506:             if (v.Timestamp >= DateTime.UtcNow.AddHours(3).AddDays(-7))
  507:             {
  508:                 adjustedStatisticsList.Add(v);
  509:             }
  510:         }
  511: 
  512:         return adjustedStatisticsList.OrderBy(u => u.Timestamp.Ticks).ToList();
  513:     }
  514:         */
  515:  
  516:         ////////////////////////////////////////////////////////////////////////////
  517:  
  518:         /// <summary>
  519:         ///
  520:         /// </summary>
  521:         public static List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue> FilterAndKeepDataFromNDays(List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue> timestampValuelist)
  522:         {
  523:             var dataToKeepFromPastNDays = 30;
  524:             var now = DateTime.UtcNow.AddHours(3);
  525:             var list = new List<Ia.Ngn.Cl.Model.Business.Nokia.Sdc.TransactionTimestampValue>(timestampValuelist.Count);
  526:  
  527:             foreach (var timestampValue in timestampValuelist)
  528:             {
  529:                 if (now.AddDays(-dataToKeepFromPastNDays) < timestampValue.Timestamp) list.Add(timestampValue);
  530:             }
  531:  
  532:             return list;
  533:         }
  534:  
  535:         ////////////////////////////////////////////////////////////////////////////
  536:         ////////////////////////////////////////////////////////////////////////////
  537:     }
  538:  
  539:     ////////////////////////////////////////////////////////////////////////////
  540:     ////////////////////////////////////////////////////////////////////////////
  541: }