docs: public int insertPointAt(double x, double y, int groupIndex, int indexInGroup) {
  		final int groupCount = getGroupCount();
  
  		if (groupIndex < 0) {
  			throw new IndexOutOfBoundsException(groupIndex + "<0"); //$NON-NLS-1$
  		}
  		if (groupIndex >= groupCount) {
  			throw new IndexOutOfBoundsException(groupIndex + ">=" + groupCount); //$NON-NLS-1$
  		}
  
  		int pointIndex;
  
  		if (this.pointCoordinates == null) {
  			this.pointCoordinates = new double[] {x, y};
  			this.partIndexes = null;
  			pointIndex = 0;
  		} else {
  			final int startIndex = firstInGroup(groupIndex);
  
  			// Be sure that the member's index is in the group index's range
  			final int groupMemberCount = getPointCountInGroup(groupIndex);
  			final int g;
  			if (indexInGroup < 0) {
  				g = 0;
  			} else if (indexInGroup > groupMemberCount) {
  				g = groupMemberCount;
  			} else {
  				g = indexInGroup;
  			}
  
  			// Move the start/end indexes to corresponds to the bounds of the new points
  			pointIndex = startIndex + g * 2;
  
  			// Update the array of points
  			double[] pts = new double[this.pointCoordinates.length + 2];
  			System.arraycopy(this.pointCoordinates, 0, pts, 0, pointIndex);
  			System.arraycopy(this.pointCoordinates, pointIndex, pts, pointIndex + 2, this.pointCoordinates.length - pointIndex);
  			pts[pointIndex] = x;
  			pts[pointIndex + 1] = y;
  			this.pointCoordinates = pts;
  			pts = null;
  
  			//Shift the following groups's indexes
  			if (this.partIndexes != null) {
  				for (int idx = groupIndex; idx < this.partIndexes.length; ++idx) {
  					this.partIndexes[idx] += 2;
  				}
  			}
  
  			pointIndex /= 2;
  		}
  
  		fireShapeChanged();
  		fireElementChanged();
  
  		return pointIndex;
  	}