private void draw(
      Object parentGroup,
      GeometryIndex parentIndex,
      LinearRing linearRing,
      GraphicsContext graphics) {
    String groupName = baseName;
    if (parentIndex != null) {
      groupName += "." + editingService.getIndexService().format(parentIndex);
    }
    Composite edgeGroup = getOrCreateGroup(parentGroup, groupName + ".edges");
    Composite vertexGroup = getOrCreateGroup(parentGroup, groupName + ".vertices");

    Coordinate[] coordinates = linearRing.getCoordinates();
    if (coordinates != null) {
      // Check if we have to draw the background as well (if there are controllers defined for it):
      GraphicsController controller = createGeometryController(parentIndex);
      if (controller != null) {
        Polygon polygon =
            mapWidget.getMapModel().getGeometryFactory().createPolygon(linearRing, null);
        graphics.drawPolygon(parentGroup, groupName + ".background", polygon, new ShapeStyle());
        graphics.setController(parentGroup, groupName + ".background", controller);
      }

      // Draw individual edges:
      int max = coordinates.length;
      if (!styleService.isCloseRingWhileInserting()
          && editingService.getEditingState() == GeometryEditState.INSERTING
          && editingService
              .getIndexService()
              .isChildOf(parentIndex, editingService.getInsertIndex())) {
        max--;
      }
      for (int i = 1; i < max; i++) {
        GeometryIndex edgeIndex =
            editingService
                .getIndexService()
                .addChildren(parentIndex, GeometryIndexType.TYPE_EDGE, i - 1);
        String identifier = baseName + "." + editingService.getIndexService().format(edgeIndex);

        LineString edge =
            linearRing
                .getGeometryFactory()
                .createLineString(new Coordinate[] {coordinates[i - 1], coordinates[i]});
        graphics.drawLine(edgeGroup, identifier, edge, findEdgeStyle(edgeIndex));
        graphics.setController(edgeGroup, identifier, createEdgeController(edgeIndex));
      }

      addInivisibleShapeToGraphicsContext(graphics, vertexGroup);
      for (int i = 0; i < coordinates.length - 1; i++) {
        GeometryIndex vertexIndex =
            editingService
                .getIndexService()
                .addChildren(parentIndex, GeometryIndexType.TYPE_VERTEX, i);
        String identifier = baseName + "." + editingService.getIndexService().format(vertexIndex);
        addShapeToGraphicsContext(
            graphics, vertexGroup, identifier, coordinates[i], findVertexStyle(vertexIndex));
        graphics.setController(vertexGroup, identifier, createVertexController(vertexIndex));
      }
    }
  }
  public void onChangeEditingState(GeometryEditChangeStateEvent event) {
    switch (event.getEditingState()) {
      case DRAGGING:
        mapWidget.setCursor(Cursor.MOVE);
        break;
      case IDLE:
      default:
        mapWidget.setCursorString(mapWidget.getDefaultCursorString());
        redraw();

        // Remove the temporary insert move line:
        if (editingService.getInsertIndex() != null) {
          String id =
              baseName
                  + "."
                  + editingService.getIndexService().format(editingService.getInsertIndex());
          Object parentGroup = groups.get(id.substring(0, id.lastIndexOf('.')) + ".edges");
          mapWidget.getVectorContext().deleteElement(parentGroup, insertMoveEdgeId1);
          mapWidget.getVectorContext().deleteElement(parentGroup, insertMoveEdgeId2);
        }
    }
  }
  public void onCoordinateSnapAttempt(CoordinateSnapEvent event) {
    if (editingService.getEditingState() == GeometryEditState.INSERTING) {
      String identifier =
          baseName + "." + editingService.getIndexService().format(editingService.getInsertIndex());
      Object parentGroup =
          groups.get(identifier.substring(0, identifier.lastIndexOf('.')) + ".vertices");

      Coordinate temp = event.getTo();
      Coordinate coordinate =
          mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp);
      addShapeToGraphicsContext(
          mapWidget.getVectorContext(),
          parentGroup,
          identifier,
          coordinate,
          event.hasSnapped() ? styleService.getVertexSnappedStyle() : new ShapeStyle());
    }
  }
  public void onTentativeMove(GeometryEditTentativeMoveEvent event) {
    try {
      Coordinate[] vertices =
          editingService
              .getIndexService()
              .getSiblingVertices(editingService.getGeometry(), editingService.getInsertIndex());
      String geometryType =
          editingService
              .getIndexService()
              .getGeometryType(editingService.getGeometry(), editingService.getInsertIndex());

      if (vertices != null && Geometry.LINE_STRING.equals(geometryType)) {
        String identifier =
            baseName
                + "."
                + editingService.getIndexService().format(editingService.getInsertIndex());
        Object parentGroup =
            groups.get(identifier.substring(0, identifier.lastIndexOf('.')) + ".edges");

        Coordinate temp1 = event.getOrigin();
        Coordinate temp2 = event.getCurrentPosition();
        Coordinate c1 =
            mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp1);
        Coordinate c2 =
            mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp2);

        LineString edge =
            mapWidget
                .getMapModel()
                .getGeometryFactory()
                .createLineString(new Coordinate[] {c1, c2});
        mapWidget
            .getVectorContext()
            .drawLine(
                parentGroup, insertMoveEdgeId1, edge, styleService.getEdgeTentativeMoveStyle());
      } else if (vertices != null && Geometry.LINEAR_RING.equals(geometryType)) {
        String identifier =
            baseName
                + "."
                + editingService.getIndexService().format(editingService.getInsertIndex());
        Object parentGroup =
            groups.get(identifier.substring(0, identifier.lastIndexOf('.')) + ".edges");

        // Line 1
        Coordinate temp1 = event.getOrigin();
        Coordinate temp2 = event.getCurrentPosition();
        Coordinate c1 =
            mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp1);
        Coordinate c2 =
            mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp2);
        LineString edge =
            mapWidget
                .getMapModel()
                .getGeometryFactory()
                .createLineString(new Coordinate[] {c1, c2});
        mapWidget
            .getVectorContext()
            .drawLine(
                parentGroup, insertMoveEdgeId1, edge, styleService.getEdgeTentativeMoveStyle());

        // Line 2
        if (styleService.isCloseRingWhileInserting()) {
          temp1 = vertices[vertices.length - 1];
          c1 = mapWidget.getMapModel().getMapView().getWorldViewTransformer().worldToPan(temp1);
          edge =
              mapWidget
                  .getMapModel()
                  .getGeometryFactory()
                  .createLineString(new Coordinate[] {c1, c2});
          mapWidget
              .getVectorContext()
              .drawLine(
                  parentGroup, insertMoveEdgeId2, edge, styleService.getEdgeTentativeMoveStyle());
        }
      }
    } catch (GeometryIndexNotFoundException e) {
      throw new IllegalStateException(e);
    }
  }