internal static int LineStringText(bool b_ring, com.epl.geometry.AttributeStreamOfDbl zs, com.epl.geometry.AttributeStreamOfDbl ms, com.epl.geometry.AttributeStreamOfDbl position, com.epl.geometry.AttributeStreamOfInt32 paths, com.epl.geometry.AttributeStreamOfInt8 path_flags
                                           , com.epl.geometry.WktParser wkt_parser)
        {
            // At start of LineStringText
            int current_token = wkt_parser.CurrentToken();
            int point_count   = 0;

            if (current_token == com.epl.geometry.WktParser.WktToken.empty)
            {
                return(point_count);
            }
            bool   b_start_path = true;
            double startx       = com.epl.geometry.NumberUtils.TheNaN;
            double starty       = com.epl.geometry.NumberUtils.TheNaN;
            double startz       = com.epl.geometry.NumberUtils.TheNaN;
            double startm       = com.epl.geometry.NumberUtils.TheNaN;

            current_token = wkt_parser.NextToken();
            while (current_token != com.epl.geometry.WktParser.WktToken.right_paren)
            {
                // At start of x
                double x = wkt_parser.CurrentNumericLiteral();
                wkt_parser.NextToken();
                double y = wkt_parser.CurrentNumericLiteral();
                wkt_parser.NextToken();
                double z = com.epl.geometry.NumberUtils.TheNaN;
                double m = com.epl.geometry.NumberUtils.TheNaN;
                if (wkt_parser.HasZs())
                {
                    z = wkt_parser.CurrentNumericLiteral();
                    wkt_parser.NextToken();
                }
                if (wkt_parser.HasMs())
                {
                    m = wkt_parser.CurrentNumericLiteral();
                    wkt_parser.NextToken();
                }
                current_token = wkt_parser.CurrentToken();
                bool b_add_point = true;
                if (b_ring && point_count >= 2 && current_token == com.epl.geometry.WktParser.WktToken.right_paren)
                {
                    // If the last point in the ring is not equal to the start
                    // point, then let's add it.
                    if ((startx == x || (com.epl.geometry.NumberUtils.IsNaN(startx) && com.epl.geometry.NumberUtils.IsNaN(x))) && (starty == y || (com.epl.geometry.NumberUtils.IsNaN(starty) && com.epl.geometry.NumberUtils.IsNaN(y))) && (!wkt_parser.HasZs() || startz == z || (com.epl.geometry.NumberUtils
                                                                                                                                                                                                                                                                                    .IsNaN(startz) && com.epl.geometry.NumberUtils.IsNaN(z))) && (!wkt_parser.HasMs() || startm == m || (com.epl.geometry.NumberUtils.IsNaN(startm) && com.epl.geometry.NumberUtils.IsNaN(m))))
                    {
                        b_add_point = false;
                    }
                }
                if (b_add_point)
                {
                    if (b_start_path)
                    {
                        b_start_path = false;
                        startx       = x;
                        starty       = y;
                        startz       = z;
                        startm       = m;
                    }
                    point_count++;
                    AddToStreams(zs, ms, position, x, y, z, m);
                }
            }
            if (point_count == 1)
            {
                point_count++;
                AddToStreams(zs, ms, position, startx, starty, startz, startm);
            }
            paths.Add(position.Size() / 2);
            path_flags.Add(unchecked ((byte)0));
            return(point_count);
        }
        /// <exception cref="System.Exception"/>
        private static com.epl.geometry.Geometry ImportFromJsonMultiPath(bool b_polygon, com.epl.geometry.JsonReader parser, com.epl.geometry.AttributeStreamOfDbl @as, com.epl.geometry.AttributeStreamOfDbl bs)
        {
            if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY)
            {
                throw new com.epl.geometry.GeometryException("failed to parse multipath: array of array of vertices is expected");
            }
            com.epl.geometry.MultiPath multipath;
            if (b_polygon)
            {
                multipath = new com.epl.geometry.Polygon();
            }
            else
            {
                multipath = new com.epl.geometry.Polyline();
            }
            com.epl.geometry.AttributeStreamOfInt32 parts     = (com.epl.geometry.AttributeStreamOfInt32)com.epl.geometry.AttributeStreamBase.CreateIndexStream(0);
            com.epl.geometry.AttributeStreamOfDbl   position  = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(2, 0);
            com.epl.geometry.AttributeStreamOfInt8  pathFlags = (com.epl.geometry.AttributeStreamOfInt8)com.epl.geometry.AttributeStreamBase.CreateByteStream(0);
            // set up min max variables
            double[] buf          = new double[4];
            double[] start        = new double[4];
            int      point_count  = 0;
            int      path_count   = 0;
            byte     pathFlag     = b_polygon ? unchecked ((byte)com.epl.geometry.PathFlags.enumClosed) : 0;
            int      requiredSize = b_polygon ? 3 : 2;

            // At start of rings
            while (parser.NextToken() != com.epl.geometry.JsonReader.Token.END_ARRAY)
            {
                if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY)
                {
                    throw new com.epl.geometry.GeometryException("failed to parse multipath: ring/path array is expected");
                }
                int  pathPointCount = 0;
                bool b_first        = true;
                int  sz             = 0;
                int  szstart        = 0;
                parser.NextToken();
                while (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.END_ARRAY)
                {
                    if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY)
                    {
                        throw new com.epl.geometry.GeometryException("failed to parse multipath: array is expected, rings/paths vertices consist of arrays of cooridinates");
                    }
                    sz = 0;
                    while (parser.NextToken() != com.epl.geometry.JsonReader.Token.END_ARRAY)
                    {
                        buf[sz++] = ReadDouble(parser);
                    }
                    if (sz < 2)
                    {
                        throw new com.epl.geometry.GeometryException("failed to parse multipath: each vertex array has to have at least 2 elements");
                    }
                    parser.NextToken();
                    do
                    {
                        if (position.Size() == point_count * 2)
                        {
                            int c = point_count * 3;
                            if (c % 2 != 0)
                            {
                                c++;
                            }
                            // have to be even
                            if (c < 8)
                            {
                                c = 8;
                            }
                            else
                            {
                                if (c < 32)
                                {
                                    c = 32;
                                }
                            }
                            position.Resize(c);
                        }
                        position.Write(2 * point_count, buf[0]);
                        position.Write(2 * point_count + 1, buf[1]);
                        if (@as.Size() == point_count)
                        {
                            int c = (point_count * 3) / 2;
                            // have to be even
                            if (c < 4)
                            {
                                c = 4;
                            }
                            else
                            {
                                if (c < 16)
                                {
                                    c = 16;
                                }
                            }
                            @as.Resize(c);
                        }
                        if (sz > 2)
                        {
                            @as.Write(point_count, buf[2]);
                        }
                        else
                        {
                            @as.Write(point_count, com.epl.geometry.NumberUtils.NaN());
                        }
                        if (bs.Size() == point_count)
                        {
                            int c = (point_count * 3) / 2;
                            // have to be even
                            if (c < 4)
                            {
                                c = 4;
                            }
                            else
                            {
                                if (c < 16)
                                {
                                    c = 16;
                                }
                            }
                            bs.Resize(c);
                        }
                        if (sz > 3)
                        {
                            bs.Write(point_count, buf[3]);
                        }
                        else
                        {
                            bs.Write(point_count, com.epl.geometry.NumberUtils.NaN());
                        }
                        if (b_first)
                        {
                            path_count++;
                            parts.Add(point_count);
                            pathFlags.Add(pathFlag);
                            b_first  = false;
                            szstart  = sz;
                            start[0] = buf[0];
                            start[1] = buf[1];
                            start[2] = buf[2];
                            start[3] = buf[3];
                        }
                        point_count++;
                        pathPointCount++;
                    }while (pathPointCount < requiredSize && parser.CurrentToken() == com.epl.geometry.JsonReader.Token.END_ARRAY);
                }
                if (b_polygon && pathPointCount > requiredSize && sz == szstart && start[0] == buf[0] && start[1] == buf[1] && start[2] == buf[2] && start[3] == buf[3])
                {
                    // remove the end point that is equal to the start point.
                    point_count--;
                    pathPointCount--;
                }
                if (pathPointCount == 0)
                {
                    continue;
                }
            }
            // skip empty paths
            if (point_count != 0)
            {
                parts.Resize(path_count);
                pathFlags.Resize(path_count);
                if (point_count > 0)
                {
                    parts.Add(point_count);
                    pathFlags.Add(unchecked ((byte)0));
                }
                com.epl.geometry.MultiPathImpl mp_impl = (com.epl.geometry.MultiPathImpl)multipath._getImpl();
                mp_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION, position);
                mp_impl.SetPathFlagsStreamRef(pathFlags);
                mp_impl.SetPathStreamRef(parts);
            }
            return(multipath);
        }