public static List <AbstractRetrievePoints> LoadTagClassesRecorded(
            String inputFilePath,
            String outputDirectory,
            String timeResolution,
            int numYears,
            int pageSize,
            PIServer piServer,
            PISystem piSystem,
            int numParallelTasks,
            Logger logger)
        {
            var inputLines = LoadInputFile(inputFilePath);

            List <AbstractRetrievePoints> tagClasses = new List <AbstractRetrievePoints>();

            Parallel.ForEach(
                inputLines,
                new ParallelOptions {
                MaxDegreeOfParallelism = numParallelTasks
            },
                (String[] line) =>
            {
                string tagName         = line[0];
                string startTimeString = line[1];
                string endTimeString   = line[2];

                PIPoint tag;
                try
                {
                    tag = PIPoint.FindPIPoint(piServer, tagName);
                    AFTime startTime      = new AFTime(startTimeString);
                    AFTime endTime        = new AFTime(endTimeString);
                    AFTimeRange timeRange = new AFTimeRange(startTime, endTime);

                    string startTimeStamp = startTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    string endTimeStamp   = endTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    lock (logger) { logger.Log($"{startTimeStamp} : {endTimeStamp}, {tagName}"); }
                    lock (tagClasses)
                    {
                        tagClasses.Add(new PIRecordedPointRetrievalClass(
                                           tag,
                                           timeRange,
                                           outputDirectory,
                                           PIRandomFunctionsUtil.ParseTimeResolutionString(timeResolution),
                                           numYears,
                                           pageSize,
                                           logger));
                    }
                }
                catch (Exception e)
                {
                    logger.Log("Exception: could not FindPiPoint: " + e.ToString());
                }
            });

            return(tagClasses);
        }
        public static List <AbstractRetrievePoints> LoadAttributeClassesRecorded(
            String inputFilePath,
            String outputDirectory,
            String timeResolution,
            int numYears,
            int pageSize,
            PIServer piServer,
            PISystem piSystem,
            AFDatabase database,
            int numParallelTasks,
            Logger logger)
        {
            var inputLines = new List <String[]>();

            using (var inputStreamReader = new StreamReader(inputFilePath))
            {
                while (!inputStreamReader.EndOfStream)
                {
                    inputLines.Add(inputStreamReader.ReadLine().Split(','));
                }
            }

            List <AbstractRetrievePoints> tagClasses = new List <AbstractRetrievePoints>();

            Parallel.ForEach(
                inputLines,
                new ParallelOptions {
                MaxDegreeOfParallelism = numParallelTasks
            },
                (String[] line) =>
            {
                string tagName         = line[0];
                string startTimeString = line[1];
                string endTimeString   = line[2];

                PIPoint tag;
                try
                {
                    AFAttribute attribute = AFUtil.FindAttribute(database, tagName);
                    tag = attribute.PIPoint;

                    AFTime startTime      = new AFTime(startTimeString);
                    AFTime endTime        = new AFTime(endTimeString);
                    AFTimeRange timeRange = new AFTimeRange(startTime, endTime);

                    string startTimeStamp = startTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    string endTimeStamp   = endTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    lock (logger) { logger.Log($"{startTimeStamp} : {endTimeStamp}, {tagName}"); }
                    lock (tagClasses)
                    {
                        tagClasses.Add(new AFRecordedAttributeRetrievalClass(
                                           attribute,
                                           timeRange,
                                           outputDirectory,
                                           PIRandomFunctionsUtil.ParseTimeResolutionString(timeResolution),
                                           numYears,
                                           pageSize,
                                           logger));
                    }
                }
                catch (Exception e)
                {
                    logger.Log("Exception: could not FindPiPoint: " + e.ToString());
                }
            });

            return(tagClasses);
        }
        public static List <AbstractRetrievePoints> LoadTagClassesInterpolated(
            String inputFilePath,
            String outputDirectory,
            String timeResolution,
            int numYears,
            int pageSize,
            PIServer piServer,
            PISystem piSystem,
            int numParallelTasks,
            Logger logger)
        {
            var inputLines = new List <String[]>();

            using (var inputStreamReader = new StreamReader(inputFilePath))
            {
                while (!inputStreamReader.EndOfStream)
                {
                    inputLines.Add(inputStreamReader.ReadLine().Split(','));
                }
            }

            List <AbstractRetrievePoints> tagClasses = new List <AbstractRetrievePoints>();

            Parallel.ForEach(
                inputLines,
                new ParallelOptions {
                MaxDegreeOfParallelism = numParallelTasks
            },
                (String[] line) =>
            {
                string tagName         = line[0];
                string startTimeString = line[1];
                string endTimeString   = line[2];
                string intervalString  = line[3];

                PIPoint tag;
                try
                {
                    tag = PIPoint.FindPIPoint(piServer, tagName);

                    AFTime startTime = new AFTime(startTimeString);
                    AFTime nextTime  = AFQueryUtil.GetNextRecordedValue(tag, startTime).Timestamp;
                    if (nextTime > startTime)
                    {
                        startTime = new AFTime(nextTime.UtcTime.Date);
                    }
                    AFTime endTime        = new AFTime(endTimeString);
                    AFTimeRange timeRange = new AFTimeRange(startTime, endTime);
                    AFTimeSpan timeSpan   = new AFTimeSpan(TimeSpan.FromSeconds(Int32.Parse(intervalString)));

                    string startTimeStamp = startTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    string endTimeStamp   = endTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss");
                    lock (logger) { logger.Log($"{startTimeStamp} : {timeSpan} : {endTimeStamp}, {tagName}"); }

                    lock (tagClasses)
                    {
                        tagClasses.Add(new PIInterpolatedPointRetrievalClass(
                                           tag,
                                           timeRange,
                                           timeSpan,
                                           outputDirectory,
                                           PIRandomFunctionsUtil.ParseTimeResolutionString(timeResolution),
                                           numYears,
                                           pageSize,
                                           logger));
                    }
                }
                catch (Exception e)
                {
                    logger.Log("Exception: could not FindPiPoint: " + e.ToString());
                }
            });

            return(tagClasses);
        }