The proposed solution by Jon Snyder provided us with a general idea, but did not fully work for in the end (especially extending OpenLayers.Layer.Vector wasn't necessary for this task, based on OpenLayers 2.1x).
We created a class YourApp.Handler.EndPointsPath (extending OpenLayers.Handler.Path), where the function geometryClone() returns a new geometry of type YourApp.Geometry.EndPointsPath.
We then patched the function drawGeometry() in OpenLayers.Renderer.Elements to draw this new geometry:
OpenLayers.Util.extend(OpenLayers.Renderer.Elements.prototype, {
drawGeometry: function (geometry, style, featureId) {
var cl = geometry.CLASS_NAME;
var rendered = true,
i, len;
if ((cl === "OpenLayers.Geometry.Collection") ||
(cl === "OpenLayers.Geometry.MultiPoint") ||
(cl === "OpenLayers.Geometry.MultiLineString") ||
(cl === "OpenLayers.Geometry.MultiPolygon") ||
(cl === "YourApp.Geometry.EndPointsPath")) {
// Iterate over all Geometry components and draw each individually
for (i = 0, len = geometry.components.length; i < len; i++) {
// Is there a style for each of the components?
if (OpenLayers.Util.isArray(style)) {
// Draw Geometry with own style
rendered = this.drawGeometry(geometry.components[i], style[i], featureId) && rendered;
} else {
// Draw Geometry with common style
rendered = this.drawGeometry(geometry.components[i], style, featureId) && rendered;
}
}
return rendered;
}
// (...standard code...)
},
eraseGeometry: function (geometry, featureId) {
var cl = geometry.CLASS_NAME,
i, len;
if ((cl === "OpenLayers.Geometry.MultiPoint") ||
(cl === "OpenLayers.Geometry.MultiLineString") ||
(cl === "OpenLayers.Geometry.MultiPolygon") ||
(cl === "YourApp.Geometry.EndPointsPath") ||
(cl === "OpenLayers.Geometry.Collection")) {
for (i = 0, len = geometry.components.length; i < len; i++) {
this.eraseGeometry(geometry.components[i], featureId);
}
// (...standard code...)
}
}
});