public void parse_thickness(string value,
                                        LensSurface surface_builder)
            {
                if (value.Length == 0)
                {
                    surface_builder.add_thickness(0.0);
                    return;
                }

                if (Char.IsLetter(value[0]))
                {
                    Variable var = find_variable(value);
                    if (var != null)
                    {
                        for (int i = 0; i < var.num_scenarios(); i++)
                        {
                            string s = var.get_value(i);
                            double d = parseDouble(s);
                            surface_builder.add_thickness(d);
                        }
                    }
                    else
                    {
                        //fprintf (stderr, "Variable %s was not found\n", value);
                        surface_builder.add_thickness(0.0);
                    }
                }
                else
                {
                    surface_builder.add_thickness(parseDouble(value));
                }
            }
            public bool parse_file(string file_name)
            {
                string[] lines           = File.ReadAllLines(file_name);
                Section? current_section = null; // Current section
                int      surface_id      = 1;    // We used to read the id from the OptBench data but

                // this doesn't always work

                foreach (string line in lines)
                {
                    string[] words = splitLine(line);
                    if (words.Length == 0)
                    {
                        continue;
                    }

                    if (words[0].StartsWith("#"))
                    {
                        // comment
                        continue;
                    }

                    if (words[0].StartsWith("["))
                    {
                        // section name
                        current_section = find_section(words[0]);
                        continue;
                    }

                    if (current_section == null)
                    {
                        continue;
                    }

                    switch (current_section)
                    {
                    case Section.DESCRIPTIVE_DATA:
                        if (words.Length >= 2 && words[0].Equals("title"))
                        {
                            descriptive_data_.set_title(words[1]);
                        }

                        break;

                    case Section.VARIABLE_DISTANCES:
                        if (words.Length >= 2)
                        {
                            Variable var = new Variable(words[0]);
                            for (int i = 1; i < words.Length; i++)
                            {
                                var.add_value(words[i]);
                            }

                            variables_.Add(var);
                        }

                        break;

                    case Section.LENS_DATA:
                    {
                        if (words.Length < 2)
                        {
                            break;
                        }
                        int         id           = surface_id++;
                        LensSurface surface_data = new LensSurface(id);
                        SurfaceType type         = SurfaceType.surface;
                        /* radius */
                        if (words[1].Equals("AS"))
                        {
                            type = SurfaceType.aperture_stop;
                            surface_data.set_radius(0.0);
                        }
                        else if (words[1].Equals("FS"))
                        {
                            type = SurfaceType.field_stop;
                            surface_data.set_radius(0.0);
                        }
                        else if (words[1].Equals("CG"))
                        {
                            surface_data.set_radius(0.0);
                            surface_data.set_is_cover_glass(true);
                        }
                        else
                        {
                            if (words[1].Equals("Infinity"))
                            {
                                surface_data.set_radius(0.0);
                            }
                            else
                            {
                                surface_data.set_radius(parseDouble(words[1]));
                            }
                        }

                        surface_data.set_surface_type(type);
                        /* thickness */
                        if (words.Length >= 3 && words[2].Length > 0)
                        {
                            parse_thickness(words[2], surface_data);
                        }

                        /* refractive index */
                        if (words.Length >= 4 && words[3].Length > 0)
                        {
                            surface_data.set_refractive_index(parseDouble(words[3]));
                        }

                        /* diameter */
                        if (words.Length >= 5 && words[4].Length > 0)
                        {
                            surface_data.set_diameter(parseDouble(words[4]));
                        }

                        /* abbe vd */
                        if (words.Length >= 6 && words[5].Length > 0)
                        {
                            surface_data.set_abbe_vd(parseDouble(words[5]));
                        }

                        if (words.Length >= 7 && words[6].Length > 0)
                        {
                            surface_data.set_glass_name(words[6]);
                        }

                        surfaces_.Add(surface_data);
                    }
                    break;

                    case Section.ASPHERICAL_DATA:
                    {
                        int            id = Int32.Parse(words[0]);
                        AsphericalData aspherical_data = new AsphericalData(id);
                        for (int i = 1; i < words.Length; i++)
                        {
                            aspherical_data.add_data(parseDouble(words[i]));
                        }

                        aspherical_data_.Add(aspherical_data);
                        LensSurface surface_builder = find_surface(id);
                        if (surface_builder == null)
                        {
//                            fprintf (
//                                    stderr,
//                                    "Ignoring aspherical data as no surface numbered %d\n",
//                                    id);
                        }
                        else
                        {
                            surface_builder.set_aspherical_data(aspherical_data);
                        }
                    }
                    break;

                    default:
                        break;
                    }
                }

                return(true);
            }