/// <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);
        }
        /// <exception cref="System.Exception"/>
        private static com.epl.geometry.Geometry ImportFromJsonMultiPoint(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 multipoint: array of vertices is expected");
            }
            int point_count = 0;

            com.epl.geometry.MultiPoint multipoint;
            multipoint = new com.epl.geometry.MultiPoint();
            com.epl.geometry.AttributeStreamOfDbl position = (com.epl.geometry.AttributeStreamOfDbl)(com.epl.geometry.AttributeStreamBase.CreateDoubleStream(2, 0));
            // At start of rings
            int sz;

            double[] buf = new double[4];
            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 multipoint: array is expected, multipoint 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 multipoint: each vertex array has to have at least 2 elements");
                }
                if (position.Size() == 2 * point_count)
                {
                    int c = point_count * 3;
                    if (c % 2 != 0)
                    {
                        c++;
                    }
                    // have to be even
                    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;
                    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;
                    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());
                }
                point_count++;
            }
            if (point_count != 0)
            {
                com.epl.geometry.MultiPointImpl mp_impl = (com.epl.geometry.MultiPointImpl)multipoint._getImpl();
                mp_impl.Resize(point_count);
                mp_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION, position);
            }
            return(multipoint);
        }