diff --git a/src/Aspect/Aspect_GenId.cdl b/src/Aspect/Aspect_GenId.cdl
index 7f5f951b95..1464155935 100644
--- a/src/Aspect/Aspect_GenId.cdl
+++ b/src/Aspect/Aspect_GenId.cdl
@@ -16,113 +16,64 @@
 
 class GenId from Aspect
 
-	---Version:
-
-	---Level: Internal
-	---Purpose: This class permits the creation and control of all
-	--	    identifiers.
-	--  Warning: An identifier is an integer.
-
-	---References:
+  ---Purpose: This class permits the creation and control of integer identifiers.
 
 uses
 
-	ListOfInteger	from TColStd
+  ListOfInteger from TColStd
 
 raises
 
-	IdentDefinitionError	from Aspect
+  IdentDefinitionError from Aspect
 
 is
 
-	Create
-		returns GenId from Aspect;
-	---Level: Internal
-	---Purpose: Creates an available set of identifiers with the lower
-	--	    bound 0 and the upper bound INT_MAX/2.
+  Create
+  returns GenId from Aspect;
+  ---Purpose: Creates an available set of identifiers with the lower bound 0 and the upper bound INT_MAX / 2.
 
-	Create ( Low, Up	: Integer from Standard )
-		returns GenId from Aspect
-	---Level: Internal
-	---Purpose: Creates an available set of identifiers with the lower
-	--	    bound <Low> and the upper bound <Up>.
-	--  Warning: Raises IdentDefinitionError if <Up> is less than <Low>.
-	raises IdentDefinitionError from Aspect;
+  Create (theLow, theUpper : Integer from Standard)
+  returns GenId from Aspect
+  ---Purpose: Creates an available set of identifiers with specified range.
+  -- Raises IdentDefinitionError if theUpper is less than theLow.
+  raises IdentDefinitionError from Aspect;
 
-	---------------------------------------------------
-	-- Category: Methods to modify the class definition
-	---------------------------------------------------
+  Free (me : in out);
+  ---Level: Internal
+  ---Purpose: Free all identifiers - make the whole range available again.
 
-	--Assign ( me	: in out;
-		 --Other	: GenId from Aspect );
-	---Level: Internal
-	---Purpose: Copies the content of <Other> into <me>.
-	---Category: Methods to modify the class definition
-	-- C++: alias operator =
+  Free (me    : in out;
+        theId : Integer from Standard);
+  ---Purpose: Free specified identifier. Warning - method has no protection against double-freeing!
 
-	Free ( me	: in out );
-	---Level: Internal
-	---Purpose: Frees all identifiers of <me>.
-	---Category: Methods to modify the class definition
+  HasFree (me)
+  returns Boolean from Standard;
+  ---Purpose: Returns true if there are available identifiers in range.
 
-	Free ( me	: in out;
-	       Id	: Integer from Standard );
-	---Level: Internal
-	---Purpose: Frees the identifier <Id> of <me>.
-	---Category: Methods to modify the class definition
+  Available (me)
+  returns Integer from Standard;
+  ---Purpose: Returns the number of available identifiers.
 
-	----------------------------
-	-- Category: Inquire methods
-	----------------------------
+  Lower (me)
+  returns Integer from Standard;
+  ---Purpose: Returns the lower identifier in range.
 
-	Available ( me )
-		returns Integer from Standard;
-	---Level: Internal
-	---Purpose: Returns the number of available identifiers of <me>.
-	---Category: Inquire methods
+  Next (me : in out)
+  returns Integer from Standard
+  ---Purpose: Returns the next available identifier.
+  -- Warning: Raises IdentDefinitionError if all identifiers are busy.
+  raises IdentDefinitionError from Aspect;
 
-	Lower ( me )
-		returns Integer from Standard;
-	---Level: Internal
-	---Purpose: Returns the lower bound of <me>.
-	---Category: Inquire methods
-
-	Next ( me	: in out )
-		returns Integer from Standard
-	---Level: Internal
-	---Purpose: Returns an available identifier of <me>.
-	--  Warning: Raises IdentDefinitionError if all identifiers are busy.
-	raises IdentDefinitionError from Aspect;
-
-	Upper ( me )
-		returns Integer from Standard;
-	---Level: Internal
-	---Purpose: Returns the upper bound of <me>.
-	---Category: Inquire methods
-
---
+  Upper (me)
+  returns Integer from Standard;
+  ---Purpose: Returns the upper identifier in range.
 
 fields
 
---
--- Class	:	Aspect_GenId
---
--- Purpose	:	Declaration of variables specific to identifiers
---
--- Reminder	:	An identifier is an integer
---
-
-	-- the current number of available identifiers
-	MyCount		:	Integer from Standard;
-
-	-- the number of identifiers
-	MyLength	:	Integer from Standard;
-
-	-- the limits for identifiers
-	MyLowerBound	:	Integer from Standard;
-	MyUpperBound	:	Integer from Standard;
-
-	-- to save free identifiers
-	MyFreeIds	:	ListOfInteger from TColStd;
+  myFreeCount  : Integer from Standard;      -- the current number of available identifiers in range, excluding freed numbers
+  myLength     : Integer from Standard;      -- the number of identifiers
+  myLowerBound : Integer from Standard;      -- the lower limit for identifiers
+  myUpperBound : Integer from Standard;      -- the upper limit for identifiers
+  myFreeIds    : ListOfInteger from TColStd; -- to save free identifiers
 
 end GenId;
diff --git a/src/Aspect/Aspect_GenId.cxx b/src/Aspect/Aspect_GenId.cxx
index 5728e57f06..bc4800ad98 100644
--- a/src/Aspect/Aspect_GenId.cxx
+++ b/src/Aspect/Aspect_GenId.cxx
@@ -14,111 +14,124 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-//-Version	
-
-//-Design	Declaration des variables specifiques aux identificateurs
-
-//-Warning	Un identificateur est un entier.
-
-//-References	
-
-//-Language	C++ 2.0
-
-//-Declarations
-
-// for the class
 #include <Aspect_GenId.ixx>
 
-//-Aliases
-
-//-Global data definitions
-
-//-Constructors
-
-//-Destructors
-
-//-Methods, in order
-
-Aspect_GenId::Aspect_GenId ():
-
-	MyCount (INT_MAX/2 + 1),
-	MyLength (INT_MAX/2 + 1),
-	MyLowerBound (0),
-	MyUpperBound (INT_MAX/2),
-	MyFreeIds () {
-
+// =======================================================================
+// function : Aspect_GenId
+// purpose  :
+// =======================================================================
+Aspect_GenId::Aspect_GenId()
+: myFreeCount  (INT_MAX / 2 + 1),
+  myLength     (INT_MAX / 2 + 1),
+  myLowerBound (0),
+  myUpperBound (INT_MAX / 2)
+{
+  //
 }
 
-Aspect_GenId::Aspect_GenId (const Standard_Integer Low, const Standard_Integer Up):MyFreeIds () {
-
-	if (Low <= Up) {
-		MyLowerBound	= Low;
-		MyUpperBound	= Up;
-		MyLength	= MyUpperBound - MyLowerBound + 1;
-		MyCount		= MyLength;
-	}
-	else
-		Aspect_IdentDefinitionError::Raise
-			("GenId Create Error: Low > Up");
-
+// =======================================================================
+// function : Aspect_GenId
+// purpose  :
+// =======================================================================
+Aspect_GenId::Aspect_GenId (const Standard_Integer theLow,
+                            const Standard_Integer theUpper)
+: myFreeCount  (theUpper - theLow + 1),
+  myLength     (theUpper - theLow + 1),
+  myLowerBound (theLow),
+  myUpperBound (theUpper)
+{
+  if (theLow > theUpper)
+  {
+    Aspect_IdentDefinitionError::Raise ("GenId Create Error: wrong interval");
+  }
 }
 
-Standard_Integer Aspect_GenId::Available () const {
-
-	return (MyCount);
-
+// =======================================================================
+// function : HasFree
+// purpose  :
+// =======================================================================
+Standard_Boolean Aspect_GenId::HasFree() const
+{
+  return myFreeCount > 0
+      || myFreeIds.Extent() > 0;
 }
 
-void Aspect_GenId::Free () {
-
-	MyCount	= MyLength;
-	MyFreeIds.Clear ();
-
+// =======================================================================
+// function : Available
+// purpose  :
+// =======================================================================
+Standard_Integer Aspect_GenId::Available() const
+{
+  return myFreeCount + myFreeIds.Extent();
 }
 
-void Aspect_GenId::Free (const Standard_Integer Id) {
-
-	if ( (Id >= MyLowerBound) && (Id <= MyUpperBound) )
-		MyFreeIds.Prepend (Id);
-
+// =======================================================================
+// function : Free
+// purpose  :
+// =======================================================================
+void Aspect_GenId::Free()
+{
+  myFreeCount = myLength;
+  myFreeIds.Clear();
 }
 
-Standard_Integer Aspect_GenId::Lower () const {
-
-	return (MyLowerBound);
-
+// =======================================================================
+// function : Free
+// purpose  :
+// =======================================================================
+void Aspect_GenId::Free (const Standard_Integer theId)
+{
+  if (theId >= myLowerBound
+   && theId <= myUpperBound)
+  {
+    if (myFreeCount + myFreeIds.Extent() + 1 == myLength)
+    {
+      myFreeCount = myLength;
+      myFreeIds.Clear();
+    }
+    else
+    {
+      myFreeIds.Prepend (theId);
+    }
+  }
 }
 
-Standard_Integer Aspect_GenId::Next () {
-
-	if (MyCount == 0)
-		Aspect_IdentDefinitionError::Raise
-			("GenId Next Error: Available == 0");
-
-Standard_Integer Id;
-
-	if (! MyFreeIds.IsEmpty ()) {
-		Id	= MyFreeIds.First ();
-		MyFreeIds.RemoveFirst ();
-	}
-	else {
-		MyCount	--;
-		Id	= MyLowerBound + MyLength - MyCount - 1;
-	}
-
-	return Id;
-
+// =======================================================================
+// function : Lower
+// purpose  :
+// =======================================================================
+Standard_Integer Aspect_GenId::Lower() const
+{
+  return myLowerBound;
 }
 
-Standard_Integer Aspect_GenId::Upper () const {
-
-	return (MyUpperBound);
+// =======================================================================
+// function : Next
+// purpose  :
+// =======================================================================
+Standard_Integer Aspect_GenId::Next()
+{
+  if (!myFreeIds.IsEmpty())
+  {
+    const Standard_Integer anId = myFreeIds.First();
+    myFreeIds.RemoveFirst();
+    return anId;
+  }
+  else if (myFreeCount < 1)
+  {
+    Aspect_IdentDefinitionError::Raise ("GenId Next Error: Available == 0");
+  }
 
+  --myFreeCount;
+  const Standard_Integer anId = myLowerBound + myLength - myFreeCount - 1;
+  return anId;
 }
 
-//void Aspect_GenId::Assign (const Aspect_GenId& Other) {
-//
-//	MyLowerBound	= Other.Lower ();
-//	MyUpperBound	= Other.Upper ();
-//
-//}
+// =======================================================================
+// function : Upper
+// purpose  :
+// =======================================================================
+Standard_Integer Aspect_GenId::Upper() const
+{
+  return myUpperBound;
+}
diff --git a/src/OpenGl/OpenGl_Clipping.cxx b/src/OpenGl/OpenGl_Clipping.cxx
index f19232b778..fd954d0af6 100755
--- a/src/OpenGl/OpenGl_Clipping.cxx
+++ b/src/OpenGl/OpenGl_Clipping.cxx
@@ -86,7 +86,7 @@ void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes,
 void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
 {
   Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
-  while (aPlaneIt.More() && myEmptyPlaneIds->Available() > 0)
+  while (aPlaneIt.More() && myEmptyPlaneIds->HasFree())
   {
     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
     if (Contains (aPlane))
@@ -113,9 +113,12 @@ void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const Equa
     aPlaneIt.Next();
   }
 
-  while (aPlaneIt.More() && myEmptyPlaneIds->Available() == 0)
+  if (!myEmptyPlaneIds->HasFree())
   {
-    thePlanes.Remove (aPlaneIt);
+    while (aPlaneIt.More())
+    {
+      thePlanes.Remove (aPlaneIt);
+    }
   }
 }
 
diff --git a/tests/bugs/vis/bug25052 b/tests/bugs/vis/bug25052
new file mode 100644
index 0000000000..966059e72a
--- /dev/null
+++ b/tests/bugs/vis/bug25052
@@ -0,0 +1,48 @@
+puts "==========="
+puts "OCC25052"
+puts "==========="
+puts ""
+##########################################################################
+# Visualization - activation of all Clipping Planes within driver limit leads to broken planes management
+##########################################################################
+
+set Image1 ${imagedir}/${casename}_1.png
+set Image9 ${imagedir}/${casename}_9.png
+
+box b -30 -30 -30 70 80 90
+
+vinit
+vsetdispmode 1
+vdisplay b
+vfit
+
+vclipplane create p1
+vclipplane change p1 equation 1 0 0 -0.1
+vclipplane create p2
+vclipplane change p2 equation 1 0 0 -0.1
+vclipplane create p3
+vclipplane change p3 equation 1 0 0 -0.1
+vclipplane create p4
+vclipplane change p4 equation 1 0 0 -0.1
+vclipplane create p5
+vclipplane change p5 equation 1 0 0 -0.1
+vclipplane create p6
+vclipplane change p6 equation 1 0 0 -0.1
+vclipplane create p7
+vclipplane change p7 equation 1 0 0 -0.1
+vclipplane create p8
+vclipplane change p8 equation 1 0 0 -0.1
+vclipplane create p9
+vclipplane change p9 equation 1 0 0 -0.1
+
+vclipplane set p1 view Driver1/Viewer1/View1
+vdump ${Image1}
+vclipplane set p2 view Driver1/Viewer1/View1
+vclipplane set p3 view Driver1/Viewer1/View1
+vclipplane set p4 view Driver1/Viewer1/View1
+vclipplane set p5 view Driver1/Viewer1/View1
+vclipplane set p6 view Driver1/Viewer1/View1
+vclipplane set p7 view Driver1/Viewer1/View1
+vclipplane set p8 view Driver1/Viewer1/View1
+vclipplane set p9 view Driver1/Viewer1/View1
+vdump ${Image9}