private MapShapeModelCollection ProcessItems(IRandomAccessStream shapeStream, ShapefileRecordInfoCollection recordInfos, CancellationTokenSource cancellationTokenSource)
        {
            if (cancellationTokenSource.IsCancellationRequested)
            {
                return(null);
            }

            int itemCount = recordInfos.Count;
            int maxDegreeOfParallelism = Environment.ProcessorCount;

            if (itemCount < maxDegreeOfParallelism)
            {
                maxDegreeOfParallelism = itemCount;
            }

            int remainder  = itemCount % maxDegreeOfParallelism;
            int multiplier = (itemCount / maxDegreeOfParallelism) + (remainder > 0 ? 1 : 0);

            var token = cancellationTokenSource.Token;
            List <Task <MapShapeModelCollection> > tasks = new List <Task <MapShapeModelCollection> >();

            for (int i = 0; i < maxDegreeOfParallelism; i++)
            {
                int start = i * multiplier;
                int end   = Math.Min((i + 1) * multiplier, itemCount);

                ParseShapeTaskState taskState = new ParseShapeTaskState()
                {
                    Start   = start,
                    End     = end,
                    Records = recordInfos,
                    Stream  = shapeStream,
                    CancellationTokenSource = cancellationTokenSource,
                    CoordinateConverter     = this.CoordinateValueConverter
                };

                var task = Task.Factory.StartNew <Task <MapShapeModelCollection> >(ParseShapes, taskState, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Current).Unwrap();

                tasks.Add(task);
            }

            Task.WaitAll(tasks.ToArray());

            MapShapeModelCollection models = tasks[0].Result;

            for (int i = 1; i < maxDegreeOfParallelism; i++)
            {
                var modelsToMerge = tasks[i].Result;
                if (modelsToMerge == null)
                {
                    continue;
                }

                foreach (var model in modelsToMerge)
                {
                    models.Add(model);
                }
            }

            models.BoundingRect = recordInfos.BoundingRect;

            return(models);
        }
        private static Task <MapShapeModelCollection> ParseShapes(object state)
        {
            ParseShapeTaskState taskState = (ParseShapeTaskState)state;
            var cancellationTokenSource   = taskState.CancellationTokenSource;
            var token = cancellationTokenSource.Token;

            var task = Task.Factory.StartNew(async() =>
            {
                using (var shapeStream = taskState.Stream.CloneStream())
                {
                    int start = taskState.Start;
                    int end   = taskState.End;
                    var coordinateConverter = taskState.CoordinateConverter;
                    var records             = taskState.Records;

                    MapShapeModelCollection shapeModels = new MapShapeModelCollection();

                    for (int i = start; i < end; i++)
                    {
                        if (cancellationTokenSource.IsCancellationRequested)
                        {
                            return(null);
                        }

                        int contentOffset = records[i].ContentOffset;
                        shapeStream.Seek((ulong)contentOffset);

                        int contentLength = records[i].ContentLength;
                        byte[] content    = new byte[contentLength];

                        await shapeStream.ReadAsync(content.AsBuffer(), (uint)contentLength, InputStreamOptions.Partial);

                        EsriShapeType shapeType = (EsriShapeType)BitConverter.ToInt32(content, 0);
                        if (shapeModels.Type == EsriShapeType.NullShape)
                        {
                            shapeModels.Type = shapeType;
                        }

                        // TODO: Consider specific support for "M" types (PointM, MultipointM, PolygonM) that support measure coordinate -- is this the Bubble visualization?.
                        switch (shapeType)
                        {
                        case EsriShapeType.NullShape:
                            shapeModels.Add(new NullShapeModel());
                            break;

                        case EsriShapeType.Point:
                        case EsriShapeType.PointM:
                        case EsriShapeType.PointZ:
                            CreatePoint(content, shapeModels, 4, coordinateConverter);
                            break;

                        case EsriShapeType.Polyline:
                        case EsriShapeType.PolylineM:
                        case EsriShapeType.PolylineZ:
                            CreatePolyline(content, shapeModels, coordinateConverter);
                            break;

                        case EsriShapeType.Polygon:
                        case EsriShapeType.PolygonM:
                        case EsriShapeType.PolygonZ:
                            CreatePolygon(content, shapeModels, coordinateConverter);
                            break;

                        default:
                            throw new NotSupportedException("The supported ESRI shape types are Point(MZ), Polyline(MZ), and Polygon(MZ).");
                        }
                    }

                    return(shapeModels);
                }
            },
                                             token).Unwrap();

            return(task);
        }