void CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex < 0 || e.RowIndex >= _grid.RowCount)
            {
                return;
            }

            // Отрисовываем картинку описывающую член типа, а затем содержимое ячейки.

            var row = _grid.Rows[e.RowIndex];
            var r   = e.CellBounds;

            if (e.ColumnIndex == 0 && row.Tag != null)
            {
                var member   = ((TypeMembers)row.Tag).Value;
                var imgIndex = NUtils.GetGlyphIndex(member);

                e.Paint(r, e.PaintParts);
                e.Graphics.DrawImage(imageList1.Images[imgIndex], r.X + _imageSize - 2, r.Y + (r.Height - _imageSize) / 2,
                                     _imageSize, _imageSize);
                e.Handled = true;
            }
            else if (row.Tag == null && e.ColumnIndex > 0)
            {
                e.PaintBackground(r, true);
                e.Handled = true;
            }
        }
        private StringBuilder MakeStubsForTypeMembers(IGrouping <FixedType.Class, MemberImplInfo> stubInfos)
        {
            var writer      = new System.IO.StringWriter();
            var members     = stubInfos.ToArray();
            var isInterface = stubInfos.Key.IsInterface;
            var ty          = isInterface ? stubInfos.Key : _ty.GetMemType();

            foreach (var memberImplInfo in members)
            {
                var member             = memberImplInfo.Member;
                var @explicit          = memberImplInfo.Explicit;
                var accessModifier     = memberImplInfo.AccessModifier;
                var implementationName = memberImplInfo.ImplementationName;

                if (isInterface)
                {
                    NUtils.GenerateMemberImplementation(writer, _source.FileIndex,
                                                        ty, member, @explicit, accessModifier, implementationName,
                                                        _cbGenerateXmlDoc.Checked);
                }
                else
                {
                    // Генерируем override-методы. Для них нужно сформировать правильны модификатор доступа.
                    var am = (member.Attributes | NemerleAttributes.Override)
                             & ~(NemerleAttributes.Abstract | NemerleAttributes.Virtual | NemerleAttributes.SpecialName);
                    var acessMods = am.ToString().ToLower().Replace(",", "");

                    NUtils.GenerateMemberImplementation(writer, _source.FileIndex,
                                                        ty, member, false, acessMods, "",
                                                        _cbGenerateXmlDoc.Checked);
                }

                writer.WriteLine();                 // разделяем члены пустой строкой
            }

            return(writer.GetStringBuilder());
        }
// ReSharper disable ParameterTypeCanBeEnumerable.Local
        private void MakeChanges(IGrouping <FixedType.Class, MemberImplInfo>[] stubs, LanguagePreferences pref, EditArray editArray)
// ReSharper restore ParameterTypeCanBeEnumerable.Local
        {
            var newLine = Environment.NewLine;

            foreach (var stub in stubs)
            {
                var sb = MakeStubsForTypeMembers(stub);

                // На данном этапе в "sb" находится текст заглушек для членов тела которых отбиты одной табуляцией на отступ.
                // Заменяем этот табы на отступ указанный в настройках студии для Nemerle.
                // TODO: Надо сразу генерировать правлиьные отступы, а не пользоваться табами, так как отступы
                // могут быть не кратными размеру табуляции. При этом отступы должны дополняться пробелами.
                // подроности смотри в MakeIndentString().

                if (!pref.InsertTabs && pref.IndentSize == 1)
                {
                    sb.Replace("\t", pref.MakeIndentString());
                }

                // Кроме того члены не имеют отсупа от левого края. Отступ должен совпадать с отступом
                // типа в который помещаются плюс один отступ.
                // Кроме того пользователю будет удобно если добавляемые члены будут добавлены после
                // последнего члена того же (т.е. типа чьи члены реализуются) типа уже имеющегося в данном типе.
                // Таким образом мы должны попытаться найти уже реализованные типы. В них найти самый послединй,
                // и вставить новые члены после него. Если в текущем типе (_ty) еще не было реализовано членов
                // подтипа (например, интерфейса) к которому относятся добавляемые члены, то производим вставку
                // в конец текущего типа.

                TextPoint pt;
                string    indent;

                var lastImplementedMembers = NUtils.GetLastImplementedMembersOfInterface(_ty, stub.Key);

                #region Calc indent and insertion point

                if (lastImplementedMembers.IsSome)
                {
                    // Используем meber.Value для получения места вставки
                    var endLine = lastImplementedMembers.Value.Location.EndLine;
                    var text    = _source.GetLine(endLine);
                    indent = text.GetLiadingSpaces();
                    pt     = new TextPoint(endLine + 1, 1);
                    //TODO: Этот код рассчитывает на то, что за членом не идет многострочного коментария
                    // или другого члена. Надо бы сделать реализацию не закладывающуюся на это.
                }
                else                 // Ни одного члена этого интерфейса не реализовано в классе...
                {
                    // Оборачиваем реализуемые методы в #region
                    if (_cbGenerateRegion.Checked)
                    {
                        sb.Insert(0, "#region " + stub.Key + "  Members" + newLine + newLine);
                        sb.AppendLine("#endregion" + newLine);
                    }
                    // Вставляем описание интерфейса в конец класса
                    var endLine = _ty.Location.EndLine;
                    var text    = _source.GetLine(endLine);
                    indent  = text.GetLiadingSpaces();
                    pt      = new TextPoint(endLine, 1);
                    indent += pref.MakeIndentString();
                    //TODO: Этот код рассчитывает на то, что конец типа распологается на отдельной строке.
                    // Надо бы сделать реализацию не закладывающуюся на это.
                }

                #endregion

                sb.Insert(0, indent);
                sb.Replace("\n", "\n" + indent);
                TrimEnd(sb);

                var inertLoc = new Location(_source.FileIndex, pt, pt);
                editArray.Add(new EditSpan(inertLoc.ToTextSpan(), sb.ToString()));
            }
        }