0029993: Visualization - AIS_TextLabel computes selection primitive only for attachme...
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
index c0317b7..3db6e67 100644 (file)
@@ -28,7 +28,7 @@
 #include <Font_BRepFont.hxx>
 #include <Font_BRepTextBuilder.hxx>
 #include <Font_FontMgr.hxx>
-
+#include <Message.hxx>
 #include <NCollection_List.hxx>
 
 #include <OSD_Chronometer.hxx>
 
 #include <Select3D_SensitiveSegment.hxx>
 #include <Select3D_SensitivePrimitiveArray.hxx>
-#include <Select3D_SensitiveTriangle.hxx>
-#include <Select3D_SensitiveCurve.hxx>
 #include <Select3D_SensitivePoint.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <StdPrs_Curve.hxx>
@@ -159,7 +157,6 @@ extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
                                            const Handle(AIS_InteractiveObject)& theAISObj,
                                            Standard_Boolean theReplaceIfExists = Standard_True);
-extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
 extern Handle(AIS_InteractiveContext)& TheAISContext();
 
 namespace
@@ -310,7 +307,7 @@ namespace
     if ((aMapOfArgs.IsBound ("xaxis") && !aMapOfArgs.IsBound ("zaxis"))
     || (!aMapOfArgs.IsBound ("xaxis") &&  aMapOfArgs.IsBound ("zaxis")))
     {
-      std::cout << "Syntax error: -xaxis and -zaxis parameters are to set together.\n";
+      Message::SendFail ("Syntax error: -xaxis and -zaxis parameters are to set together");
       return Standard_False;
     }
 
@@ -335,7 +332,7 @@ namespace
 
       if (!aZDir.IsNormal (aXDir, M_PI / 180.0))
       {
-        std::cout << "Syntax error - parameters 'xaxis' and 'zaxis' are not applied as VectorX is not normal to VectorZ\n";
+        Message::SendFail ("Syntax error - parameters 'xaxis' and 'zaxis' are not applied as VectorX is not normal to VectorZ");
         return Standard_False;
       }
 
@@ -361,7 +358,7 @@ namespace
       }
       else if (aValues->Size() != 0)
       {
-        std::cout << "Syntax error: -hidelabels expects parameter 'on' or 'off' after.\n";
+        Message::SendFail ("Syntax error: -hidelabels expects parameter 'on' or 'off' after");
         return Standard_False;
       }
 
@@ -381,7 +378,7 @@ namespace
       }
       else if (aValues->Size() != 0)
       {
-        std::cout << "Syntax error: -hidearrows expects parameter 'on' or 'off' after.\n";
+        Message::SendFail ("Syntax error: -hidearrows expects parameter 'on' or 'off' after");
         return Standard_False;
       }
 
@@ -397,7 +394,7 @@ namespace
       NCollection_List<Prs3d_DatumParts> aParts;
       if (aValues->Size() < 2)
       {
-        std::cout << "Syntax error: -color wrong parameters.\n";
+        Message::SendFail ("Syntax error: -color wrong parameters");
         return Standard_False;
       }
 
@@ -406,7 +403,7 @@ namespace
       Quantity_Color aColor;
       if (!convertToColor (aValues, aColor))
       {
-        std::cout << "Syntax error: -color wrong parameters.\n";
+        Message::SendFail ("Syntax error: -color wrong parameters");
         return Standard_False;
       }
 
@@ -429,7 +426,7 @@ namespace
       Quantity_Color aColor;
       if (!convertToColor (aValues, aColor))
       {
-        std::cout << "Syntax error: -textcolor wrong parameters.\n";
+        Message::SendFail ("Syntax error: -textcolor wrong parameters");
         return Standard_False;
       }
       theTrihedron->SetTextColor (aColor);
@@ -440,7 +437,7 @@ namespace
       Quantity_Color aColor;
       if (!convertToColor (aValues, aColor))
       {
-        std::cout << "Syntax error: -arrowcolor wrong parameters.\n";
+        Message::SendFail ("Syntax error: -arrowcolor wrong parameters");
         return Standard_False;
       }
       theTrihedron->SetArrowColor (aColor);
@@ -451,7 +448,7 @@ namespace
       NCollection_List<Prs3d_DatumAttribute> anAttributes;
       if (aValues->Size() != 2)
       {
-        std::cout << "Syntax error: -attribute wrong parameters.\n";
+        Message::SendFail ("Syntax error: -attribute wrong parameters");
         return Standard_False;
       }
 
@@ -470,7 +467,7 @@ namespace
       if (aValues->Size() < 2
       || !convertToDatumPart (aValues->Value (1), aDatumPart))
       {
-        std::cout << "Syntax error: -priority wrong parameters.\n";
+        Message::SendFail ("Syntax error: -priority wrong parameters");
         return Standard_False;
       }
       theTrihedron->SetSelectionPriority (aDatumPart, aValues->Value (2).IntegerValue());
@@ -489,7 +486,7 @@ namespace
       }
       else
       {
-        std::cout << "Syntax error: -labels wrong parameters.\n";
+        Message::SendFail ("Syntax error: -labels wrong parameters");
         return Standard_False;
       }
     }
@@ -500,7 +497,7 @@ namespace
       if (aValues->Size() < 1
       || !convertToDatumAxes (aValues->Value (1), aDatumAxes))
       {
-        std::cout << "Syntax error: -drawaxes wrong parameters.\n";
+        Message::SendFail ("Syntax error: -drawaxes wrong parameters");
         return Standard_False;
       }
       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
@@ -542,6 +539,35 @@ namespace
     }
     return Standard_False;
   }
+
+  //! Auxiliary function to parse font strict level argument
+  static Standard_Integer parseFontStrictLevel (const Standard_Integer theArgNb,
+                                                const char**           theArgVec,
+                                                Font_StrictLevel&      theLevel)
+  {
+    if (theArgNb >= 1)
+    {
+      TCollection_AsciiString anArg (theArgVec[0]);
+      anArg.LowerCase();
+      if (anArg == "any")
+      {
+        theLevel = Font_StrictLevel_Any;
+        return 1;
+      }
+      else if (anArg == "aliases")
+      {
+        theLevel = Font_StrictLevel_Aliases;
+        return 1;
+      }
+      else if (anArg == "strict")
+      {
+        theLevel = Font_StrictLevel_Strict;
+        return 1;
+      }
+    }
+    theLevel = Font_StrictLevel_Strict;
+    return 0;
+  }
 }
 
 //==============================================================================
@@ -555,7 +581,7 @@ static int VTrihedron2D (Draw_Interpretor& /*theDI*/,
 {
   if (theArgsNum != 2)
   {
-    std::cerr << theArgVec[0]<< " error.\n";
+    Message::SendFail() << "Syntax error: wrong number of arguments.";
     return 1;
   }
 
@@ -564,7 +590,7 @@ static int VTrihedron2D (Draw_Interpretor& /*theDI*/,
 
   if (aShapes.Extent() != 1)
   {
-    std::cerr << "Error: wrong number of selected shapes.\n";
+    Message::SendFail ("Error: wrong number of selected shapes.");
     return 1;
   }
 
@@ -613,7 +639,7 @@ static int VTrihedron (Draw_Interpretor& ,
 {
   if (theArgsNb < 2)
   {
-    std::cout << "Syntax error: the wrong number of input parameters.\n";
+    Message::SendFail ("Syntax error: the wrong number of input parameters");
     return 1;
   }
 
@@ -631,7 +657,7 @@ static int VTrihedron (Draw_Interpretor& ,
     aTrihedron = Handle(AIS_Trihedron)::DownCast (anObject);
     if (aTrihedron.IsNull())
     {
-      std::cout << "Syntax error: no trihedron with this name.\n";
+      Message::SendFail ("Syntax error: no trihedron with this name");
       return 1;
     }
   }
@@ -827,7 +853,7 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c
 
   if (TheAISContext()->NbSelected() != 1)
   {
-    std::cerr << "Error: Wrong number of selected shapes.\n";
+    Message::SendFail ("Error: Wrong number of selected shapes.");
     return 1;
   }
 
@@ -836,7 +862,7 @@ static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const c
   Handle(AIS_Plane) aPlane = Handle(AIS_Plane)::DownCast (aTest);
   if (aPlane.IsNull())
   {
-    std::cerr << "Error: Selected shape is not a plane.\n";
+    Message::SendFail ("Error: Selected shape is not a plane.");
     return 1;
   }
 
@@ -906,7 +932,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
     if ( !strcasecmp(argv[0], "vaxis")) {
       if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
       {
-        std::cerr << "Error: Wrong number of selected shapes.\n";
+        Message::SendFail ("Error: Wrong number of selected shapes.");
         return 1;
       }
 
@@ -915,14 +941,14 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
       {
         if (aShapes.Extent() != 2)
         {
-          std::cerr << "Error: Wron number of selected shapes.\n";
+          Message::SendFail ("Error: Wrong number of selected shapes.");
           return 1;
         }
 
         const TopoDS_Shape& aShapeB = aShapes.Last();
         if (aShapeB.ShapeType() != TopAbs_VERTEX)
         {
-          std::cerr << "Syntax error: You should select two vertices or one edge.\n";
+          Message::SendFail ("Syntax error: You should select two vertices or one edge.");
           return 1;
         }
 
@@ -959,7 +985,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
     {
       if (aShapes.Extent() != 2)
       {
-        std::cerr << "Error: Wrong number of selected shapes.\n";
+        Message::SendFail ("Error: Wrong number of selected shapes.");
         return 1;
       }
 
@@ -968,7 +994,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
       if (!(aShapeA.ShapeType() == TopAbs_EDGE
          && aShapeB.ShapeType() == TopAbs_VERTEX))
       {
-        std::cerr << "Syntax error: You should select face and then vertex.\n";
+        Message::SendFail ("Syntax error: You should select face and then vertex.");
         return 1;
       }
 
@@ -992,7 +1018,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
     {
       if (aShapes.Extent() != 2)
       {
-        std::cerr << "Error: Wrong number of selected shapes.\n";
+        Message::SendFail ("Error: Wrong number of selected shapes.");
         return 1;
       }
 
@@ -1001,7 +1027,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
       if (!(aShapeA.ShapeType() == TopAbs_EDGE
          && aShapeB.ShapeType() == TopAbs_VERTEX))
       {
-        std::cerr << "Syntax error: You should select face and then vertex.\n";
+        Message::SendFail ("Syntax error: You should select face and then vertex.");
         return 1;
       }
 
@@ -1036,8 +1062,7 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
 
 //==============================================================================
 //function : VPointBuilder
-//purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
-//Draw arg : vpoint PoinName [Xa] [Ya] [Za]
+//purpose  :
 //==============================================================================
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
@@ -1045,70 +1070,105 @@ static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
 #include <AIS_Point.hxx>
 #include <Geom_CartesianPoint.hxx>
 
-static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+static int VPointBuilder(Draw_Interpretor& ,
+                         Standard_Integer theArgNb,
+                         const char** theArgVec)
 {
-  // Declarations
-  Standard_Boolean HasArg;
-  TCollection_AsciiString name;
-
-  // Verification
-  if (argc<2 || argc>5 ) {di<<" Syntaxe error\n";return 1;}
-  if (argc==5) HasArg=Standard_True;
-  else HasArg=Standard_False;
-
-  name=argv[1];
-
-  // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
-  if (HasArg) {
-    Standard_Real thecoord[3];
-    for(Standard_Integer i=0;i<=2;i++)
-      thecoord[i]=Draw::Atof(argv[2+i]);
-    Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
-    Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
-    GetMapOfAIS().Bind (myAISPoint,name);
-    TheAISContext()->Display (myAISPoint, Standard_True);
-  }
-
-  // Il n'a pas d'arguments
-  else
+  TCollection_AsciiString aName;
+  gp_Pnt aPnt (RealLast(), 0.0, 0.0);
+  bool is2d = false, isNoSel = false;
+  for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
   {
-    TopTools_ListOfShape aShapes;
-    ViewerTest::GetSelectedShapes (aShapes);
-
-    if (aShapes.Extent() != 1)
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    if (anArg == "-2d")
+    {
+      is2d = true;
+    }
+    else if (anArg == "-nosel"
+          || anArg == "-noselection")
+    {
+      isNoSel = true;
+    }
+    else if (aName.IsEmpty())
     {
-      std::cerr << "Error: Wrong number of selected shapes.\n";
-      std::cerr << "\tYou should select one edge or vertex.\n";
+      aName = theArgVec[anArgIter];
+    }
+    else if (aPnt.X() == RealLast()
+          && anArgIter + 1 < theArgNb
+          && Draw::ParseReal (theArgVec[anArgIter + 0], aPnt.ChangeCoord().ChangeCoord (1))
+          && Draw::ParseReal (theArgVec[anArgIter + 1], aPnt.ChangeCoord().ChangeCoord (2)))
+    {
+      if (anArgIter + 2 < theArgNb
+       && TCollection_AsciiString (theArgVec[anArgIter + 2]) != "-2d"
+       && Draw::ParseReal (theArgVec[anArgIter + 2], aPnt.ChangeCoord().ChangeCoord (3)))
+      {
+        anArgIter += 2;
+      }
+      else
+      {
+        anArgIter += 1;
+      }
+    }
+    else
+    {
+      Message::SendFail() << "Syntax error at argument '" << anArg << "'\n";
       return 1;
     }
+  }
 
-    const TopoDS_Shape& aShapeA = aShapes.First();
-
-    if (aShapeA.ShapeType()==TopAbs_VERTEX )
+  if (aPnt.X() == RealLast())
+  {
+    TopTools_ListOfShape aShapes;
+    ViewerTest::GetSelectedShapes (aShapes);
+    TopoDS_Shape aShapeA;
+    if (aShapes.Extent() == 1)
     {
-      gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(aShapeA ) );
-      Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
-      Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
-      GetMapOfAIS().Bind(myAISPoint,name);
-      TheAISContext()->Display (myAISPoint, Standard_True);
+      aShapeA = aShapes.First();
     }
-    else
+    switch (!aShapeA.IsNull() ? aShapeA.ShapeType() : TopAbs_SHAPE)
     {
-      TopoDS_Edge myEdge=TopoDS::Edge(aShapeA);
-      TopoDS_Vertex myVertexA,myVertexB;
-      TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
-      gp_Pnt A=BRep_Tool::Pnt(myVertexA );
-      gp_Pnt B=BRep_Tool::Pnt(myVertexB );
-      // M est le milieu de [AB]
-      Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
-      Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
-      GetMapOfAIS().Bind(myAISPointM,name);
-      TheAISContext()->Display (myAISPointM, Standard_True);
+      case TopAbs_VERTEX:
+      {
+        aPnt = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
+        break;
+      }
+      case TopAbs_EDGE: // edge middle point
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge (aShapeA);
+        TopoDS_Vertex aVertPair[2];
+        TopExp::Vertices (anEdge, aVertPair[0], aVertPair[1]);
+        const gp_Pnt A = BRep_Tool::Pnt (aVertPair[0]);
+        const gp_Pnt B = BRep_Tool::Pnt (aVertPair[1]);
+        aPnt = (A.XYZ() + B.XYZ()) / 2;
+        break;
+      }
+      default:
+      {
+        Message::SendFail() << "Error: Wrong number of selected shapes.\n"
+                            << "\tYou should select one edge or vertex.";
+        return 1;
+      }
     }
+  }
 
+  if (is2d)
+  {
+    aPnt.SetY (-aPnt.Y());
+  }
+  Handle(Geom_CartesianPoint ) aGeomPoint = new Geom_CartesianPoint (aPnt);
+  Handle(AIS_Point) aPointPrs = new AIS_Point (aGeomPoint);
+  if (is2d)
+  {
+    aPointPrs->SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER));
+    aPointPrs->SetZLayer (Graphic3d_ZLayerId_TopOSD);
+  }
+  ViewerTest::Display (aName, aPointPrs);
+  if (isNoSel)
+  {
+    ViewerTest::GetAISContext()->Deactivate (aPointPrs);
   }
   return 0;
-
 }
 
 //==============================================================================
@@ -1142,7 +1202,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
   // Verification
   if (argc<2 || argc>6 )
   {
-    std::cout<<" Syntax error\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
   if (argc == 6 || argc==5 || argc==4)
@@ -1158,7 +1218,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
     Handle(AIS_InteractiveObject) aShapeA;
     if (!GetMapOfAIS().Find2 (argv[2], aShapeA))
     {
-      std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
+      Message::SendFail ("Syntax error: 1st name is not displayed");
       return 1;
     }
 
@@ -1171,28 +1231,28 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         Handle(AIS_InteractiveObject) aShapeB;
         if (argc<5 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
         {
-          std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
+          Message::SendFail ("Syntax error: 2nd name is not displayed");
           return 1;
         }
         // If B is not an AIS_Point
         if (aShapeB.IsNull() ||
           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
         {
-          std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
+          Message::SendFail ("Syntax error: 2nd object is expected to be an AIS_Point");
           return 1;
         }
         // The third object is an AIS_Point
         Handle(AIS_InteractiveObject) aShapeC;
         if (!GetMapOfAIS().Find2(argv[4], aShapeC)) 
         {
-          std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
+          Message::SendFail ("Syntax error: 3d name is not displayed");
           return 1; 
         }
         // If C is not an AIS_Point
         if (aShapeC.IsNull() ||
           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
         {
-          std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
+          Message::SendFail ("Syntax error: 3d object is expected to be an AIS_Point");
           return 1;
         }
 
@@ -1217,21 +1277,24 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
         {
           // B=A
-          std::cout<<"vplane error: same points\n";return 1;
+          Message::SendFail ("Error: same points");
+          return 1;
         }
         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
         {
           // C=A
-          std::cout<<"vplane error: same points\n";return 1;
+          Message::SendFail ("Error: same points");
+          return 1;
         }
         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
         {
           // C=B
-          std::cout<<"vplane error: same points\n";return 1;
+          Message::SendFail ("Error: same points");
+          return 1;
         }
 
         gp_Pnt A = aCartPointA->Pnt();
@@ -1248,11 +1311,10 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
           Standard_Integer aType = Draw::Atoi (argv[5]);
           if (aType != 0 && aType != 1)
           {
-            std::cout << "vplane error: wrong type of sensitivity!\n"
-                      << "Should be one of the following values:\n"
-                      << "0 - Interior\n"
-                      << "1 - Boundary"
-                      << std::endl;
+            Message::SendFail("Syntax error: wrong type of sensitivity.\n"
+                              "Should be one of the following values:\n"
+                              "0 - Interior\n"
+                              "1 - Boundary");
             return 1;
           }
           else
@@ -1270,14 +1332,14 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       Handle(AIS_InteractiveObject) aShapeB;
       if (argc!=4 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
       {
-        std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
+        Message::SendFail ("Syntax error: 2d name is not displayed");
         return 1;
       }
       // If B is not an AIS_Point
       if (aShapeB.IsNull() ||
         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
       {
-        std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
+        Message::SendFail ("Syntax error: 2d object is expected to be an AIS_Point");
         return 1;
       }
 
@@ -1304,11 +1366,10 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         Standard_Integer aType = Draw::Atoi (argv[4]);
         if (aType != 0 && aType != 1)
         {
-          std::cout << "vplane error: wrong type of sensitivity!\n"
-                    << "Should be one of the following values:\n"
-                    << "0 - Interior\n"
-                    << "1 - Boundary"
-                    << std::endl;
+          Message::SendFail ("Syntax error: wrong type of sensitivity!\n"
+                             "Should be one of the following values:\n"
+                             "0 - Interior\n"
+                             "1 - Boundary");
           return 1;
         }
         else
@@ -1327,14 +1388,14 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       Handle(AIS_InteractiveObject) aShapeB;
       if (argc!=4 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
       {
-        std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
+        Message::SendFail ("Syntax error: 2d name is not displayed");
         return 1;
       }
       // B should be an AIS_Point
       if (aShapeB.IsNull() ||
          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
       {
-        std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
+        Message::SendFail ("Syntax error: 2d object is expected to be an AIS_Point");
         return 1;
       }
 
@@ -1357,11 +1418,10 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         Standard_Integer aType = Draw::Atoi (argv[4]);
         if (aType != 0 && aType != 1)
         {
-          std::cout << "vplane error: wrong type of sensitivity!\n"
-                    << "Should be one of the following values:\n"
-                    << "0 - Interior\n"
-                    << "1 - Boundary"
-                    << std::endl;
+          Message::SendFail ("Syntax error: wrong type of sensitivity!\n"
+                             "Should be one of the following values:\n"
+                             "0 - Interior\n"
+                             "1 - Boundary");
           return 1;
         }
         else
@@ -1374,7 +1434,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
     // Error
     else
     {
-      std::cout<<"vplane: error 1st object is not an AIS\n";
+      Message::SendFail ("Syntax error: 1st object is not an AIS");
       return 1;
     }
   }
@@ -1390,8 +1450,8 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
     {
       if (aShapes.Extent() < 1 || aShapes.Extent() > 3)
       {
-        std::cerr << "Error: Wront number of selected shapes.\n";
-        std::cerr << "\tYou should one of variant: face, edge and vertex or three vertices.\n";
+        Message::SendFail() << "Error: Wront number of selected shapes.\n"
+                            << "\tYou should one of variant: face, edge and vertex or three vertices.";
         return 1;
       }
 
@@ -1403,7 +1463,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
           const TopoDS_Shape& aShapeB = aShapes.Last();
           if (aShapeB.ShapeType() != TopAbs_EDGE)
           {
-            std::cerr << "Syntax error: Together with vertex should be edge.\n";
+            Message::SendFail ("Syntax error: Together with vertex should be edge.");
             return 1;
           }
 
@@ -1415,7 +1475,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
           {
             // The vertex is on the edge
-            std::cout<<" vplane: error point is on the edge\n";
+            Message::SendFail ("Error: point is on the edge");
             return 1;
           }
           else
@@ -1445,7 +1505,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
           if (!(aShapeB.ShapeType() == TopAbs_VERTEX
              && aShapeC.ShapeType() == TopAbs_VERTEX))
           {
-            std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
+            Message::SendFail ("Syntax error: You should one of variant: face, edge and vertex or three vertices.");
             return 1;
           }
 
@@ -1460,7 +1520,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         }
         else
         {
-          std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
+          Message::SendFail ("Syntax error: You should one of variant: face, edge and vertex or three vertices.");
           return 1;
         }
       }
@@ -1468,14 +1528,14 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       {
         if (aShapes.Extent() != 2)
         {
-          std::cerr << "Error: wrong number of selected shapes.\n";
+          Message::SendFail ("Error: wrong number of selected shapes.");
           return 1;
         }
 
         const TopoDS_Shape& aShapeB = aShapes.Last();
         if (aShapeB.ShapeType() != TopAbs_VERTEX)
         {
-          std::cerr << "Syntax error: Together with edge should be vertex.\n";
+          Message::SendFail ("Syntax error: Together with edge should be vertex.");
           return 1;
         }
 
@@ -1487,7 +1547,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
         {
           // The vertex is on the edge
-          std::cout<<" vplane: error point is on the edge\n";
+          Message::SendFail ("Error point is on the edge");
           return 1;
         }
 
@@ -1516,13 +1576,13 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
         }
         else
         {
-          std::cout<<" vplane: error\n";
+          Message::SendFail ("Error: surface is not Plane");
           return 1;
         }
       }
       else
       {
-        std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
+        Message::SendFail ("Syntax error: You should one of variant: face, edge and vertex or three vertices");
         return 1;
       }
     }
@@ -1534,7 +1594,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
     {
       if (aShapes.Extent() != 2)
       {
-        std::cerr << "Error: Wrong number of selected shapes.\n";
+        Message::SendFail ("Error: Wrong number of selected shapes.");
         return 1;
       }
 
@@ -1548,7 +1608,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       if (!(aShapeA->ShapeType() == TopAbs_VERTEX
          && aShapeB->ShapeType() == TopAbs_FACE))
       {
-        std::cerr << "Syntax error: you should select face and vertex.\n";
+        Message::SendFail ("Syntax error: you should select face and vertex.");
         return 1;
       }
 
@@ -1568,7 +1628,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       }
       else
       {
-        std::cerr << "Error: Builded surface is not a plane.\n";
+        Message::SendFail ("Error: Builded surface is not a plane.");
         return 1;
       }
     }
@@ -1580,7 +1640,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
     {
       if (aShapes.Extent() != 2)
       {
-        std::cerr << "Error: wrong number of selected shapes.\n";
+        Message::SendFail ("Error: wrong number of selected shapes.");
         return 1;
       }
 
@@ -1595,7 +1655,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       if (!(aShapeA->ShapeType() == TopAbs_EDGE
          && aShapeB->ShapeType() == TopAbs_FACE))
       {
-        std::cerr << "Error: you should select edge and face.\n";
+        Message::SendFail ("Error: you should select edge and face.");
         return 1;
       }
 
@@ -1620,7 +1680,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
           >Precision::Confusion())
       {
         // the edge is not parallel to the face
-        std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
+        Message::SendFail ("Error: the edge is not parallel to the face");
         return 1;
       }
       // the edge is OK
@@ -1640,7 +1700,7 @@ static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
       }
       else
       {
-        std::cout<<" vplaneortho: error\n";
+        Message::SendFail ("Error: surface is not Plane");
         return 1;
       }
     }
@@ -1657,15 +1717,13 @@ static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb
   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
   if (aContextAIS.IsNull())
   {
-    std::cout << theArgVec[0] << "AIS context is not available.\n";
+    Message::SendFail ("Error: no active viewer.");
     return 1;
   }
 
   if (theArgsNb < 3 || theArgsNb > 11)
   {
-    std::cerr << theArgVec[0] 
-              << ": incorrect number of command arguments.\n"
-              << "Type help for more information.\n";
+    Message::SendFail ("Syntax error: wrong number of arguments.");
     return 1;
   }
 
@@ -1677,9 +1735,7 @@ static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb
 
   if ( aPlane.IsNull() )
   {
-    std::cout << theArgVec[0] 
-              << ": there is no interactive plane with the given name."
-              << "Type help for more information.\n";
+    Message::SendFail() << "Syntax error: there is no interactive plane with the given name '" << aName << "'.";
     return 1;
   }
 
@@ -1849,7 +1905,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
     ViewerTest::GetSelectedShapes (aShapes);
     if (aShapes.Extent() != 2)
     {
-      std::cerr << "Error: wrong number of selected shapes.\n";
+      Message::SendFail ("Error: wrong number of selected shapes.");
       return 1;
     }
 
@@ -1859,7 +1915,7 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
     if (!(aShapeA.ShapeType() == TopAbs_VERTEX
        && aShapeB.ShapeType() == TopAbs_VERTEX))
     {
-      std::cerr << "Error: you should select two different vertex.\n";
+      Message::SendFail ("Error: you should select two different vertex.");
       return 1;
     }
 
@@ -1971,8 +2027,7 @@ void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelect
                                     const Standard_Integer /*theMode*/)
 {
   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
-  Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
-      myCircle, myFilledStatus);
+  Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle (anEntityOwner, myCircle->Circ(), myFilledStatus);
   theSelection->Add(aSensitiveCircle);
 }
 
@@ -2025,8 +2080,8 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
   // Verification of the arguments
   if (argc>6 || argc<2) 
   { 
-    std::cout << "vcircle error: expect 4 arguments.\n"; 
-    return 1; // TCL_ERROR 
+    Message::SendFail ("Syntax error: wrong number of arguments");
+    return 1;
   }
 
   // There are all arguments
@@ -2047,8 +2102,8 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
     {
       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
       {
-        std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
-        return 1; // TCL_ERROR 
+        Message::SendFail ("Error: 2d argument is unexpected to be a point");
+        return 1;
       }
       // The third object must be a point
       Handle(AIS_InteractiveObject) theShapeC;
@@ -2056,8 +2111,8 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       if (theShapeC.IsNull() ||
         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
       {
-        std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
-        return 1; // TCL_ERROR 
+        Message::SendFail ("Error: 3d argument is unexpected to be a point");
+        return 1;
       }
         // tag
         // Verify that the three points are different
@@ -2082,24 +2137,24 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
         {
-          std::cout << "vcircle error: Same points.\n"; 
-          return 1; // TCL_ERROR 
+          Message::SendFail ("Error: Same points");
+          return 1;
         }
         // Test A=C
         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
         {
-          std::cout << "vcircle error: Same points.\n"; 
-          return 1; // TCL_ERROR 
+          Message::SendFail ("Error: Same points");
+          return 1;
         }
         // Test B=C
         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
         {
-          std::cout << "vcircle error: Same points.\n"; 
-          return 1;// TCL_ERROR 
+          Message::SendFail ("Error: Same points");
+          return 1;
         }
         // Construction of the circle
         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
@@ -2109,12 +2164,12 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
         {
           theGeomCircle = Cir.Value();
         }
-        catch (StdFail_NotDone)
+        catch (StdFail_NotDone const&)
         {
-          std::cout << "vcircle error: can't create circle\n";
-          return -1; // TCL_ERROR
+          Message::SendFail ("Error: can't create circle");
+          return -1;
         }
-        
+
         DisplayCircle(theGeomCircle, aName, isFilled);
     }
 
@@ -2126,14 +2181,14 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       if (theShapeB->Type() != AIS_KOI_Datum || 
         theShapeB->Signature() != 1 ) 
       {
-        std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
-        return 1; // TCL_ERROR 
+        Message::SendFail ("Error: 2d element is a unexpected to be a point");
+        return 1;
       }
       // Check that the radius is >= 0
       if (Draw::Atof(argv[4]) <= 0 ) 
       {
-        std::cout << "vcircle error: the radius must be >=0.\n"; 
-        return 1; // TCL_ERROR 
+        Message::SendFail ("Syntax error: the radius must be >=0");
+        return 1;
       }
 
       // Recover the normal to the plane
@@ -2156,10 +2211,10 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       {
         theGeomCircle = Cir.Value();
       }
-      catch (StdFail_NotDone)
+      catch (StdFail_NotDone const&)
       {
-        std::cout << "vcircle error: can't create circle\n";
-        return -1; // TCL_ERROR
+        Message::SendFail ("Error: can't create circle");
+        return -1;
       }
 
       DisplayCircle(theGeomCircle, aName, isFilled);
@@ -2169,8 +2224,8 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
     // Error
     else
     {
-      std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
-      return 1; // TCL_ERROR 
+      Message::SendFail ("Error: 1st argument has an unexpected type");
+      return 1;
     }
 
   }
@@ -2185,7 +2240,7 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
     ViewerTest::GetSelectedShapes (aShapes);
     if (aShapes.Extent() != 3 && aShapes.Extent() != 2)
     {
-      std::cerr << "Error: Wrong number of selected shapes.\n";
+      Message::SendFail ("Error: Wrong number of selected shapes.");
       return 1;
     }
 
@@ -2194,7 +2249,7 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
     {
       if (aShapes.Extent() != 3)
       {
-        std::cerr << "Error: wrong number of selected shapes.\n";
+        Message::SendFail ("Error: wrong number of selected shapes.");
         return 1;
       }
 
@@ -2209,7 +2264,7 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       // Get isFilled
       Standard_Boolean isFilled;
       std::cout << "Enter filled status (0 or 1)\n";
-      cin >> isFilled;
+      std::cin >> isFilled;
 
       // Construction of the circle
       gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
@@ -2222,10 +2277,10 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       {
         theGeomCircle = Cir.Value();
       }
-      catch (StdFail_NotDone)
+      catch (StdFail_NotDone const&)
       {
-        std::cout << "vcircle error: can't create circle\n";
-        return -1; // TCL_ERROR
+        Message::SendFail ("Error: can't create circle");
+        return -1;
       }
 
       DisplayCircle(theGeomCircle, aName, isFilled);
@@ -2240,13 +2295,13 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       do 
       {
         std::cout << " Enter the value of the radius:\n";
-        cin >> theRad;
+        std::cin >> theRad;
       } while (theRad <= 0);
       
       // Get filled status
       Standard_Boolean isFilled;
       std::cout << "Enter filled status (0 or 1)\n";
-      cin >> isFilled;
+      std::cin >> isFilled;
 
       // Recover the normal to the plane. tag
       TopoDS_Face myFace = TopoDS::Face(aShapeA);
@@ -2267,17 +2322,17 @@ static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const
       {
         theGeomCircle = Cir.Value();
       }
-      catch (StdFail_NotDone)
+      catch (StdFail_NotDone const&)
       {
-        std::cout << "vcircle error: can't create circle\n";
-        return -1; // TCL_ERROR
+        Message::SendFail ("Error: can't create circle");
+        return -1;
       }
 
       DisplayCircle(theGeomCircle, aName, isFilled);
     }
     else
     {
-      std::cerr << "Error: You should select face and vertex or three vertices.\n";
+      Message::SendFail ("Error: You should select face and vertex or three vertices.");
       return 1;
     }
   }
@@ -2296,13 +2351,13 @@ static int VDrawText (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (theArgsNb < 3)
   {
-    std::cout << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Syntax error: wrong number of arguments. See usage:");
     theDI.PrintHelp (theArgVec[0]);
     return 1;
   }
   else if (aContext.IsNull())
   {
-    std::cout << "Error: no active view!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -2349,7 +2404,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (anArgIt + 3 >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2360,48 +2415,23 @@ static int VDrawText (Draw_Interpretor& theDI,
     }
     else if (aParam == "-color")
     {
-      if (anArgIt + 1 >= theArgsNb)
-      {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
-        return 1;
-      }
-
-      TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
-      Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
-      if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
-      {
-        anArgIt += 1;
-        aTextPrs->SetColor (aNameOfColor);
-        continue;
-      }
-      else if (anArgIt + 3 >= theArgsNb)
-      {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
-        return 1;
-      }
-
-      TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
-      TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
-      if (!aColor.IsRealValue()
-       || !aGreen.IsRealValue()
-       || !aBlue.IsRealValue())
+      Quantity_Color aColor;
+      Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgsNb - anArgIt - 1,
+                                                           theArgVec + anArgIt + 1,
+                                                           aColor);
+      if (aNbParsed == 0)
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error at '" << aParam << "'";
         return 1;
       }
-
-      const Graphic3d_Vec3d anRGB (aColor.RealValue(),
-                                   aGreen.RealValue(),
-                                   aBlue.RealValue());
-
-      aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
-      anArgIt += 3;
+      anArgIt += aNbParsed;
+      aTextPrs->SetColor (aColor);
     }
     else if (aParam == "-halign")
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'";
         return 1;
       }
 
@@ -2421,7 +2451,7 @@ static int VDrawText (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error at '" << aParam << "'";
         return 1;
       }
     }
@@ -2429,7 +2459,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2453,7 +2483,7 @@ static int VDrawText (Draw_Interpretor& theDI,
       }
       else
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error at '" << aParam << "'";
         return 1;
       }
     }
@@ -2461,7 +2491,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2471,7 +2501,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2481,7 +2511,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2491,7 +2521,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2500,7 +2530,7 @@ static int VDrawText (Draw_Interpretor& theDI,
       Font_FontAspect aFontAspect = Font_FA_Undefined;
       if (!parseFontStyle (anOption, aFontAspect))
       {
-        std::cout << "Error: unknown font aspect '" << anOption << "'.\n";
+        Message::SendFail() << "Syntax error: unknown font aspect '" << anOption << "'";
         return 1;
       }
       aTextPrs->SetFontAspect (aFontAspect);
@@ -2509,7 +2539,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2519,7 +2549,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (anArgIt + 6 >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -2539,12 +2569,21 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       aTextPrs->SetFlipping (Standard_True);
     }
+    else if (aParam == "-ownanchor")
+    {
+      if (++anArgIt >= theArgsNb)
+      {
+        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        return 1;
+      }
+      aTextPrs->SetOwnAnchorPoint (Draw::Atoi (theArgVec[anArgIt]) == 1);
+    }
     else if (aParam == "-disptype"
           || aParam == "-displaytype")
     {
       if (++anArgIt >= theArgsNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
       TCollection_AsciiString aType (theArgVec[anArgIt]);
@@ -2563,49 +2602,24 @@ static int VDrawText (Draw_Interpretor& theDI,
         aDisplayType = Aspect_TODT_SHADOW;
       else
       {
-        std::cout << "Error: wrong display type '" << aType << "'.\n";
+        Message::SendFail() << "Syntax error: wrong display type '" << aType << "'";
         return 1;
       }
     }
     else if (aParam == "-subcolor"
           || aParam == "-subtitlecolor")
     {
-      if (anArgIt + 1 >= theArgsNb)
-      {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
-        return 1;
-      }
-
-      TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
-      Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
-      if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
-      {
-        anArgIt += 1;
-        aTextPrs->SetColorSubTitle (aNameOfColor);
-        continue;
-      }
-      else if (anArgIt + 3 >= theArgsNb)
-      {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
-        return 1;
-      }
-
-      TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
-      TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
-      if (!aColor.IsRealValue()
-       || !aGreen.IsRealValue()
-       || !aBlue.IsRealValue())
+      Quantity_Color aColor;
+      Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgsNb - anArgIt - 1,
+                                                           theArgVec + anArgIt + 1,
+                                                           aColor);
+      if (aNbParsed == 0)
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Syntax error at '" << aParam << "'";
         return 1;
       }
-
-      const Graphic3d_Vec3d anRGB (aColor.RealValue(),
-                                   aGreen.RealValue(),
-                                   aBlue.RealValue());
-
-      aTextPrs->SetColorSubTitle (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
-      anArgIt += 3;
+      anArgIt += aNbParsed;
+      aTextPrs->SetColorSubTitle (aColor);
     }
     else if (aParam == "-2d")
     {
@@ -2616,7 +2630,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     {
       if (anArgIt + 2 >= theArgsNb)
       {
-        std::cerr << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'.";
         return 1;
       }
 
@@ -2626,7 +2640,7 @@ static int VDrawText (Draw_Interpretor& theDI,
       if (!aX.IsIntegerValue()
        || !aY.IsIntegerValue())
       {
-        std::cerr << "Error: wrong syntax at '" << aParam << "'.\n";
+        Message::SendFail() << "Error: wrong syntax at '" << aParam << "'.";
         return 1;
       }
       if (anArgIt + 1 < theArgsNb)
@@ -2643,7 +2657,7 @@ static int VDrawText (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: unknown argument '" << aParam << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << aParam << "'";
       return 1;
     }
   }
@@ -2708,7 +2722,6 @@ static int VDrawText (Draw_Interpretor& theDI,
 #include <TopoDS_Shape.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopAbs.hxx>
-#include <StdSelect_ShapeTypeFilter.hxx>
 #include <AIS_InteractiveObject.hxx>
 
 
@@ -2952,13 +2965,13 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
   if (aContextAIS.IsNull())
   {
-    std::cout << "Call vinit before!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   else if (argc < 3)
   {
-    std::cout << "Use: " << argv[0]
-              << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
+    Message::SendFail() << "Syntax error: wrong number of arguments.\n"
+                        << "Use: " << argv[0] << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]";
     return 1;
   }
 
@@ -3020,8 +3033,8 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c
 
   // Setting material properties, very important for desirable visual result!
   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
-  aMat.SetAmbient  (0.2f);
-  aMat.SetSpecular (0.5f);
+  aMat.SetAmbientColor (Quantity_Color (Graphic3d_Vec3 (0.04f)));
+  aMat.SetSpecularColor(Quantity_Color (Graphic3d_Vec3 (0.50f)));
   Handle(Graphic3d_AspectFillArea3d) anAspect
     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
                                       Quantity_NOC_RED,
@@ -3055,7 +3068,7 @@ static int VComputeHLR (Draw_Interpretor& ,
   gp_Ax2 aProjAx;
   bool hasViewDirArg = false;
   Prs3d_TypeOfHLR anAlgoType = Prs3d_TOH_PolyAlgo;
-  bool toShowTangentEdges = false, toShowHiddenEdges = false;
+  bool toShowCNEdges = false, toShowHiddenEdges = false;
   int aNbIsolines = 0;
   if (Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext())
   {
@@ -3101,7 +3114,7 @@ static int VComputeHLR (Draw_Interpretor& ,
       }
       else
       {
-        std::cout << "Syntax error: unknown algo type '" << anArgNext << "'\n";
+        Message::SendFail() << "Syntax error: unknown algo type '" << anArgNext << "'";
         return 1;
       }
     }
@@ -3120,9 +3133,9 @@ static int VComputeHLR (Draw_Interpretor& ,
           || anArgCase == "-tangentedges"
           || anArgCase == "-tangent")
     {
-      toShowTangentEdges = true;
+      toShowCNEdges = true;
       if (anArgIter + 1 < theArgNb
-       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toShowTangentEdges))
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toShowCNEdges))
       {
         ++anArgIter;
       }
@@ -3143,7 +3156,7 @@ static int VComputeHLR (Draw_Interpretor& ,
         BRepTools::Read (aSh, theArgVec[anArgIter], aBrepBuilder);
         if (aSh.IsNull())
         {
-          std::cout << "Syntax error: no shape with name " << theArgVec[anArgIter] << " found\n";
+          Message::SendFail() << "Syntax error: no shape with name " << theArgVec[anArgIter] << " found";
           return 1;
         }
       }
@@ -3167,7 +3180,7 @@ static int VComputeHLR (Draw_Interpretor& ,
     }
     else
     {
-      std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
       return 1;
     }
   }
@@ -3175,7 +3188,7 @@ static int VComputeHLR (Draw_Interpretor& ,
   if (aHlrName.IsEmpty() || aSh.IsNull()
    || (ViewerTest::GetAISContext().IsNull() && hasViewDirArg))
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -3194,19 +3207,19 @@ static int VComputeHLR (Draw_Interpretor& ,
 
     aVisible[HLRBRep_Sharp]   = aHLRToShape.VCompound();
     aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound(); // extract visible outlines
-    aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
-    if (toShowTangentEdges)
+    aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
+    if (toShowCNEdges)
     {
-      aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
+      aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
     }
     if (toShowHiddenEdges)
     {
       aHidden[HLRBRep_Sharp]   = aHLRToShape.HCompound();
       aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
-      aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
-      if (toShowTangentEdges)
+      aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
+      if (toShowCNEdges)
       {
-        aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
+        aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
       }
     }
   }
@@ -3221,10 +3234,10 @@ static int VComputeHLR (Draw_Interpretor& ,
     HLRBRep_HLRToShape aHLRToShape (aHlrAlgo);
     aVisible[HLRBRep_Sharp]   = aHLRToShape.VCompound();
     aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound();
-    aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
-    if (toShowTangentEdges)
+    aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
+    if (toShowCNEdges)
     {
-      aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
+      aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
     }
     aVisible[HLRBRep_IsoLine] = aHLRToShape.IsoLineVCompound();
 
@@ -3232,10 +3245,10 @@ static int VComputeHLR (Draw_Interpretor& ,
     {
       aHidden[HLRBRep_Sharp]   = aHLRToShape.HCompound();
       aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
-      aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
-      if (toShowTangentEdges)
+      aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
+      if (toShowCNEdges)
       {
-        aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
+        aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
       }
       aHidden[HLRBRep_IsoLine] = aHLRToShape.IsoLineHCompound();
     }
@@ -3316,6 +3329,10 @@ public:
 
   virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
 
+  //! Sets color to this interactive object
+  //! @param theColor the color to be set
+  virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
+
 private:
 
   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
@@ -3331,6 +3348,13 @@ private:
                           Standard_Integer theArgCount,
                           Standard_Integer theMaxArgs);
 
+  //! Sets color for the shading aspect of the drawer used in this interactive object
+  //! @param theColor the color to be set
+  void setColorForShadingAspect(const Quantity_Color& theColor);
+
+  //! Replaces shading aspect from myDrawer->Link() with the own shading aspect of myDrawer for this interactive object
+  void replaceShadingAspect();
+
 protected:
 
   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
@@ -3352,8 +3376,10 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
   {
     aGroup->SetGroupPrimitivesAspect (myMarkerAspect);
   }
-  aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
-  aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+  else
+  {
+    aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+  }
   aGroup->AddPrimitiveArray (myPArray);
 }
 
@@ -3445,7 +3471,7 @@ Standard_Boolean MyPArrayObject::Init (Graphic3d_TypeOfPrimitiveArray thePrimTyp
     || !myPArray->Attributes()->IsMutable()
     || (!myPArray->Indices().IsNull() && !myPArray->Indices()->IsMutable()))
     {
-      std::cout << "Syntax error: array cannot be patched\n";
+      Message::SendFail ("Syntax error: array cannot be patched");
       return Standard_False;
     }
 
@@ -3547,13 +3573,28 @@ Standard_Boolean MyPArrayObject::Init (Graphic3d_TypeOfPrimitiveArray thePrimTyp
     // unknown command
     else
     {
-      std::cout << "Syntax error: unknown argument '" << theDesc->Value(anArgIndex) << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << theDesc->Value(anArgIndex) << "'";
       return Standard_False;
     }
   }
   return Standard_True;
 }
 
+//=======================================================================
+// function : SetColor
+// purpose  :
+//=======================================================================
+void MyPArrayObject::SetColor (const Quantity_Color& theColor)
+{
+  AIS_InteractiveObject::SetColor (theColor);
+  setColorForShadingAspect (theColor);
+  if (myMarkerAspect)
+  {
+    myMarkerAspect->SetColor (theColor);
+  }
+  SynchronizeAspects();
+}
+
 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
                                        const Standard_Integer theMode)
 {
@@ -3630,6 +3671,34 @@ bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand
   return true;
 }
 
+//=======================================================================
+// function : setColorForShadingAspect
+// purpose  :
+//=======================================================================
+void MyPArrayObject::setColorForShadingAspect (const Quantity_Color& theColor)
+{
+  if (myDrawer->SetupOwnShadingAspect())
+  {
+    replaceShadingAspect();
+  }
+  myDrawer->ShadingAspect()->SetColor (theColor);
+}
+
+//=======================================================================
+// function : replaceShadingAspect
+// purpose  :
+//=======================================================================
+void MyPArrayObject::replaceShadingAspect()
+{
+  if (!myDrawer->Link())
+  {
+    return;
+  }
+  Graphic3d_MapOfAspectsToAspects anAspectReplacementMap;
+  anAspectReplacementMap.Bind (myDrawer->Link()->ShadingAspect()->Aspect(), myDrawer->ShadingAspect()->Aspect());
+  replaceAspects (anAspectReplacementMap);
+}
+
 //=============================================================================
 //function : VDrawPArray
 //purpose  : Draws primitives array from list of vertexes, bounds, edges
@@ -3640,12 +3709,12 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
   if (aContextAIS.IsNull())
   {
-    std::cout << "Error: no active Viewer\n";
+    Message::SendFail ("Error: no active Viewer");
     return 1;
   }
   else if (argc < 3)
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -3662,12 +3731,12 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
     Handle(Graphic3d_ArrayOfPrimitives) aTris = StdPrs_ShadedShape::FillTriangles (aShape);
     if (aShape.IsNull())
     {
-      std::cout << "Syntax error: shape '" << aShapeName << "' is not found\n";
+      Message::SendFail() << "Syntax error: shape '" << aShapeName << "' is not found";
       return 1;
     }
     else if (aTris.IsNull())
     {
-      std::cout << "Syntax error: shape '" << aShapeName << "' is not triangulated\n";
+      Message::SendFail() << "Syntax error: shape '" << aShapeName << "' is not triangulated";
       return 1;
     }
 
@@ -3691,7 +3760,7 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
     }
     if (aPObject.IsNull())
     {
-      std::cout << "Syntax error: object '" << aName << "' cannot be found\n";
+      Message::SendFail() << "Syntax error: object '" << aName << "' cannot be found";
       return 1;
     }
   }
@@ -3737,7 +3806,7 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
   if (aPrimType == Graphic3d_TOPA_UNDEFINED)
   {
-    std::cout << "Syntax error: unexpected type of primitives array\n";
+    Message::SendFail ("Syntax error: unexpected type of primitives array");
     return 1;
   }
 
@@ -3837,7 +3906,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
   if (aContext.IsNull())
   {
-    std::cout << "Error: no active view!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -3859,7 +3928,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       GetMapOfAIS().Find2 (aName, anObj);
       if (anObj.IsNull())
       {
-        std::cout << "Error: object '" << aName << "' is not displayed!\n";
+        Message::SendFail() << "Error: object '" << aName << "' is not displayed";
         return 1;
       }
     }
@@ -3873,7 +3942,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
     {
       if (anArgIter + 1 >= theArgNb)
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -3882,7 +3951,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       GetMapOfAIS().Find2 (aName2, anObj2);
       if (anObj2.IsNull())
       {
-        std::cout << "Error: object '" << aName2 << "' is not displayed!\n";
+        Message::SendFail() << "Error: object '" << aName2 << "' is not displayed";
         return 1;
       }
 
@@ -3894,7 +3963,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       toPrintInfo = Standard_False;
       if (anArgIter + 7 >= theArgNb)
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -3919,7 +3988,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       anArgIter += aNbParsed;
       if (aNbParsed == 0)
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -3983,7 +4052,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       {
         if (anArg == "-setscale")
         {
-          std::cout << "Syntax error at '" << anArg << "'\n";
+          Message::SendFail() << "Syntax error at '" << anArg << "'";
           return 1;
         }
 
@@ -4027,7 +4096,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       toPrintInfo = Standard_False;
       if (anArgIter + 6 >= theArgNb)
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -4078,7 +4147,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
         }
         else if (anArg == "-setrotation")
         {
-          std::cout << "Syntax error at '" << anArg << "'\n";
+          Message::SendFail() << "Syntax error at '" << anArg << "'";
           return 1;
         }
       }
@@ -4103,7 +4172,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       }
       else if (anArg == "-setlocation")
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
 
@@ -4119,7 +4188,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
       Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter, theArgVec + anArgIter, aLocVec);
       if (aNbParsed == 0)
       {
-        std::cout << "Syntax error at '" << anArg << "'\n";
+        Message::SendFail() << "Syntax error at '" << anArg << "'";
         return 1;
       }
       anArgIter = anArgIter + aNbParsed - 1;
@@ -4131,14 +4200,14 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
     }
     else
     {
-      std::cout << "Error: unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Error: unknown argument '" << anArg << "'";
       return 1;
     }
   }
 
   if (anObj.IsNull())
   {
-    std::cout << "Syntax error - wrong number of arguments\n";
+    Message::SendFail ("Syntax error - wrong number of arguments");
     return 1;
   }
   else if (!toPrintInfo)
@@ -4160,34 +4229,63 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
   return 0;
 }
 
+//! Find displayed object.
+static Handle(AIS_InteractiveObject) findConnectedObject (const TCollection_AsciiString& theName)
+{
+  Handle(AIS_InteractiveObject) aPrs;
+  if (!GetMapOfAIS().Find2 (theName, aPrs))
+  {
+    return Handle(AIS_InteractiveObject)();
+  }
+  if (Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (aPrs))
+  {
+    return aConnected;
+  }
+  else if (Handle(AIS_MultipleConnectedInteractive) aMultiCon = Handle(AIS_MultipleConnectedInteractive)::DownCast (aPrs))
+  {
+    return aMultiCon;
+  }
+
+  // replace already displayed object with connected one
+  TheAISContext()->Remove (aPrs, false);
+  Handle(AIS_ConnectedInteractive) aConnected = new AIS_ConnectedInteractive();
+  if (aPrs->HasDisplayMode())
+  {
+    aConnected->SetDisplayMode (aPrs->DisplayMode());
+  }
+  aConnected->Connect (aPrs, aPrs->LocalTransformationGeom());
+  if (!aPrs->TransformPersistence().IsNull())
+  {
+    aConnected->SetTransformPersistence (aPrs->TransformPersistence());
+  }
+  ViewerTest::Display (theName, aConnected, false);
+  return aConnected;
+}
+
 //===============================================================================================
 //function : VConnect
-//purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
-//Draw arg : vconnect name Xo Yo Zo object1 object2 ... [color=NAME]
+//purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location
 //===============================================================================================
-
-static Standard_Integer VConnect (Draw_Interpretor& /*di*/, 
-                                  Standard_Integer argc, 
-                                  const char ** argv) 
+static Standard_Integer VConnect (Draw_Interpretor& /*di*/,
+                                  Standard_Integer argc,
+                                  const char ** argv)
 {
-  // Check the viewer
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << "vconnect error : call vinit before\n";
-    return 1; // TCL_ERROR
+    Message::SendFail ("Error: no active viewer");
+    return 1;
   }
-  // Check argumnets 
   if (argc < 6)
   {
-    std::cout << "vconnect error: expect at least 5 arguments\n";
-    return 1; // TCL_ERROR
+    Message::SendFail ("Syntax error: expect at least 5 arguments");
+    return 1;
   }
 
   // Get values
   Standard_Integer anArgIter = 1;
-  TCollection_AsciiString aName (argv[anArgIter++]);
-  Handle(AIS_MultipleConnectedInteractive) anOriginObject;
+  const TCollection_AsciiString aName (argv[anArgIter++]);
+  Handle(AIS_MultipleConnectedInteractive) aMultiConObject;
   TCollection_AsciiString aColorString (argv[argc-1]);
   Standard_CString aColorName = "";
   Standard_Boolean hasColor = Standard_False;
@@ -4197,111 +4295,84 @@ static Standard_Integer VConnect (Draw_Interpretor& /*di*/,
     aColorString.Remove (1, 6);
     aColorName = aColorString.ToCString();
   }
-  Handle(AIS_InteractiveObject) anObject;
 
-  // AIS_MultipleConnectedInteractive
   const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
   for (Standard_Integer i = 5; i < aNbShapes; ++i)
   {
     TCollection_AsciiString anOriginObjectName (argv[i]);
+    Handle(AIS_InteractiveObject) anObject;
     if (aName.IsEqual (anOriginObjectName))
     {
-      std::cout << "vconnect error: equal names for connected objects\n";
+      Message::SendFail ("Syntax error: equal names for connected objects");
       continue;
     }
-    if (GetMapOfAIS().Find2 (anOriginObjectName, anObject))
-    {
-      if (anObject.IsNull())
-      {
-        std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
-        continue;
-      }
-    }
-    else
+
+    anObject = findConnectedObject (anOriginObjectName);
+    if (anObject.IsNull())
     {
-      Standard_CString aOriginName = anOriginObjectName.ToCString();
-      TopoDS_Shape aTDShape = DBRep::Get (aOriginName);
+      TopoDS_Shape aTDShape = DBRep::Get (anOriginObjectName);
       if (aTDShape.IsNull())
       {
-        std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
-        continue;
+        Message::SendFail() << "Syntax error: object " << anOriginObjectName << " doesn't exist";
+        return 1;
       }
-      anObject = new AIS_Shape (aTDShape);
+      Handle(AIS_Shape) aShapePrs = new AIS_Shape (aTDShape);
+      Handle(AIS_ConnectedInteractive) aConnectedOrig = new AIS_ConnectedInteractive();
+      aConnectedOrig->Connect (aShapePrs);
+      anObject = aConnectedOrig;
+
       aContext->Load (anObject);
       anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
     }
 
-    if (anOriginObject.IsNull())
+    if (aMultiConObject.IsNull())
     {
-      anOriginObject = new AIS_MultipleConnectedInteractive();
+      aMultiConObject = new AIS_MultipleConnectedInteractive();
     }
 
-    anOriginObject->Connect (anObject);
+    aMultiConObject->Connect (anObject);
   }
-  if (anOriginObject.IsNull())
+  if (aMultiConObject.IsNull())
   {
-    std::cout << "vconect error : can't connect input objects\n";
-    return 1; // TCL_ERROR
+    Message::SendFail ("Syntax error: can't connect input objects");
+    return 1;
   }
 
-  // Get location data
-  Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
-  Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
-  Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
-
   // Create transformation
-  gp_Vec aTranslation (aXo, aYo, aZo);
-
   gp_Trsf aTrsf; 
-  aTrsf.SetTranslationPart (aTranslation);
+  aTrsf.SetTranslationPart (gp_Vec (Draw::Atof (argv[anArgIter + 0]),
+                                    Draw::Atof (argv[anArgIter + 1]),
+                                    Draw::Atof (argv[anArgIter + 2])));
   TopLoc_Location aLocation (aTrsf);
+  anArgIter += 3;
 
-  anOriginObject->SetLocalTransformation (aTrsf);
-
-  // Check if there is another object with given name
-  // and remove it from context
-  Handle(AIS_InteractiveObject) anObj;
-  if (GetMapOfAIS().Find2 (aName, anObj))
-  {
-    TheAISContext()->Remove(anObj, Standard_False);
-    GetMapOfAIS().UnBind2(aName);
-  }
-
-  // Bind connected object to its name
-  GetMapOfAIS().Bind (anOriginObject, aName);
-
-  // Display connected object
-  TheAISContext()->Display (anOriginObject, Standard_True);
+  aMultiConObject->SetLocalTransformation (aTrsf);
 
+  ViewerTest::Display (aName, aMultiConObject, true);
   return 0;
 }
 
 //===============================================================================================
 //function : VConnectTo
 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
-//Draw arg : vconnectto name Xo Yo Zo object [-nodisplay|-noupdate|-update]
 //===============================================================================================
-
-static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, 
-                                    Standard_Integer argc, 
-                                    const char ** argv) 
+static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/,
+                                    Standard_Integer argc,
+                                    const char ** argv)
 {
-  // Check the viewer
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
   if (aContext.IsNull())
   {
-    std::cout << "vconnect error : call vinit before\n";
-    return 1; // TCL_ERROR
+    Message::SendFail ("Error: no active viewer");
+    return 1;
   }
-  // Check argumnets 
   if (argc != 6 && argc != 7)
   {
-    std::cout << "vconnect error: expect at least 5 arguments\n";
-    return 1; // TCL_ERROR
+    Message::SendFail ("Syntax error: expect at least 5 arguments");
+    return 1;
   }
 
-  // Get values
   Standard_Integer anArgIter = 1;
   TCollection_AsciiString aName (argv[anArgIter++]);
   Handle(AIS_InteractiveObject) anOriginObject;
@@ -4309,75 +4380,61 @@ static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/,
   TCollection_AsciiString anOriginObjectName(argv[5]);
   if (aName.IsEqual (anOriginObjectName))
   {
-    std::cout << "vconnect error: equal names for connected objects\n"; 
-    return 1; // TCL_ERROR
-  }
-  if (GetMapOfAIS().Find2 (anOriginObjectName, anOriginObject))
-  {
-    if (anOriginObject.IsNull())
-    {
-      std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
-      return 1; // TCL_ERROR
-    }
+    Message::SendFail ("Syntax error: equal names for connected objects");
+    return 1;
   }
-  else
+  anOriginObject = findConnectedObject (anOriginObjectName);
+  if (anOriginObject.IsNull())
   {
-    Standard_CString aOriginName = anOriginObjectName.ToCString();
-    TopoDS_Shape aTDShape = DBRep::Get (aOriginName);
+    TopoDS_Shape aTDShape = DBRep::Get (anOriginObjectName);
     if (aTDShape.IsNull())
     {
-      std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
-      return 1; // TCL_ERROR
+      Message::SendFail() << "Syntax error: object " << anOriginObjectName << " doesn't exist";
+      return 1;
     }
-    anOriginObject = new AIS_Shape (aTDShape);
-    GetMapOfAIS().Bind (anOriginObject, anOriginObjectName);
-  }
-  // Get location data
-  Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
-  Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
-  Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
-
-  // Create transformation
-  gp_Vec aTranslation (aXo, aYo, aZo);
-
-  gp_Trsf aTrsf; 
-  aTrsf.SetTranslationPart (aTranslation);
-  Handle(AIS_ConnectedInteractive) aConnected;
 
-  aConnected = new AIS_ConnectedInteractive();
-
-  aConnected->Connect (anOriginObject, aTrsf);
+    Handle(AIS_Shape) aShapePrs = new AIS_Shape (aTDShape);
+    Handle(AIS_ConnectedInteractive) aConnectedOrig = new AIS_ConnectedInteractive();
+    aConnectedOrig->Connect (aShapePrs);
 
-  // Check if there is another object with given name
-  // and remove it from context
-  Handle(AIS_InteractiveObject) anObj;
-  if (GetMapOfAIS().Find2 (aName, anObj))
-  {
-    TheAISContext()->Remove (anObj, Standard_False);
-    GetMapOfAIS().UnBind2(aName);
+    anOriginObject = aConnectedOrig;
+    GetMapOfAIS().Bind (aConnectedOrig, anOriginObjectName);
   }
 
-  // Bind connected object to its name
-  GetMapOfAIS().Bind (aConnected, aName);
+  // Create transformation
+  gp_Trsf aTrsf;
+  aTrsf.SetTranslationPart (gp_Vec (Draw::Atof (argv[anArgIter + 0]),
+                                    Draw::Atof (argv[anArgIter + 1]),
+                                    Draw::Atof (argv[anArgIter + 2])));
+  anArgIter += 3;
 
+  Handle(AIS_ConnectedInteractive) aConnected = new AIS_ConnectedInteractive();
+  aConnected->Connect (anOriginObject, aTrsf);
   if (argc == 7)
   {
     TCollection_AsciiString anArg = argv[6];
     anArg.LowerCase();
     if (anArg == "-nodisplay")
+    {
+      // bind connected object without displaying it
+      Handle(AIS_InteractiveObject) anObj;
+      if (GetMapOfAIS().Find2 (aName, anObj))
+      {
+        TheAISContext()->Remove (anObj, false);
+        GetMapOfAIS().UnBind2 (aName);
+      }
+      GetMapOfAIS().Bind (aConnected, aName);
       return 0;
+    }
 
     if (!anUpdateTool.parseRedrawMode (anArg))
     {
-      std::cout << "Warning! Unknown argument '" << anArg << "' passed, -nodisplay|-noupdate|-update expected at this point.\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
+      return 1;
     }
   }
 
-  // Display connected object
-  TheAISContext()->Display (aConnected, Standard_False);
-
+  ViewerTest::Display (aName, aConnected, false);
   return 0;
 }
 
@@ -4392,13 +4449,13 @@ static Standard_Integer VDisconnect (Draw_Interpretor& di,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << argv[0] << "ERROR : use 'vinit' command before \n";
+    Message::SendFail( "Error: no active viewer");
     return 1;
   }
   
   if (argc != 3)
   {
-    std::cout << "ERROR : Usage : " << argv[0] << " name object\n";
+    Message::SendFail() << "Syntax error: wrong number of arguments.\nUsage: " << argv[0] << " name object";
     return 1;
   }
 
@@ -4411,7 +4468,7 @@ static Standard_Integer VDisconnect (Draw_Interpretor& di,
   Handle(AIS_MultipleConnectedInteractive) anAssembly;
   if (!aMap.IsBound2 (aName) )
   {
-    std::cout << "Use 'vdisplay' before\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4441,7 +4498,7 @@ static Standard_Integer VDisconnect (Draw_Interpretor& di,
     }
     else
     {
-      std::cout << "Use 'vdisplay' before\n";
+      Message::SendFail ("Error: no active viewer");
       return 1;
     }    
   }
@@ -4455,52 +4512,50 @@ static Standard_Integer VDisconnect (Draw_Interpretor& di,
 //function : VAddConnected
 //purpose  :
 //=======================================================================
-static Standard_Integer VAddConnected (Draw_Interpretor& di,
+static Standard_Integer VAddConnected (Draw_Interpretor& ,
                                        Standard_Integer argc,
                                        const char ** argv)
 {
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << argv[0] << "error : use 'vinit' command before \n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
-  
+
   if (argc != 6)
   {
-    std::cout << argv[0] << " error: expect 5 arguments\n";
+    Message::SendFail ("Syntax error: expect 5 arguments");
     return 1;
   }
 
-  TCollection_AsciiString aName (argv[1]);
-  TCollection_AsciiString anObject (argv[5]);
-  Standard_Real aX = Draw::Atof (argv[2]);
-  Standard_Real aY = Draw::Atof (argv[3]);
-  Standard_Real aZ = Draw::Atof (argv[4]);
+  const TCollection_AsciiString aName (argv[1]);
+  const Standard_Real aX = Draw::Atof (argv[2]);
+  const Standard_Real aY = Draw::Atof (argv[3]);
+  const Standard_Real aZ = Draw::Atof (argv[4]);
+  const TCollection_AsciiString anObjectName (argv[5]);
 
   // find object
   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
   Handle(AIS_MultipleConnectedInteractive) anAssembly;
-  if (!aMap.IsBound2 (aName) )
   {
-    std::cout << "Use 'vdisplay' before\n";
-    return 1;
+    Handle(AIS_InteractiveObject) aPrs;
+    aMap.Find2 (aName, aPrs);
+    anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aPrs);
+    if (anAssembly.IsNull())
+    {
+      Message::SendFail() << "Syntax error: '" << aName << "' is not an assembly";
+      return 1;
+    }
   }
 
-  anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
-  if (anAssembly.IsNull())
+  Handle(AIS_InteractiveObject) anIObj = findConnectedObject (anObjectName);
+  if (anIObj.IsNull())
   {
-    di << "Not an assembly\n";
+    Message::SendFail() << "Syntax error: '" << anObjectName << "' is not displayed";
     return 1;
   }
 
-  Handle(AIS_InteractiveObject) anIObj;
-  if (!aMap.Find2 (anObject, anIObj))
-  {
-      std::cout << "Use 'vdisplay' before\n";
-      return 1; 
-  }
-
   gp_Trsf aTrsf;
   aTrsf.SetTranslation (gp_Vec (aX, aY, aZ));
  
@@ -4508,7 +4563,6 @@ static Standard_Integer VAddConnected (Draw_Interpretor& di,
   TheAISContext()->Display (anAssembly, Standard_False);
   TheAISContext()->RecomputeSelectionOnly (anAssembly);
   aContext->UpdateCurrentViewer();
-
   return 0;
 }
 
@@ -4523,13 +4577,13 @@ static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << argv[0] << "ERROR : use 'vinit' command before \n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   
   if (argc != 2)
   {
-    std::cout << "ERROR : Usage : " << argv[0] << " name\n";
+    Message::SendFail() << "Syntax error: wrong number of arguments.\nUsage: " << argv[0] << " name";
     return 1;
   }
 
@@ -4540,14 +4594,14 @@ static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
   Handle(AIS_MultipleConnectedInteractive) anAssembly;
   if (!aMap.IsBound2 (aName) )
   {
-    std::cout << "Use 'vdisplay' before\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
   if (anAssembly.IsNull())
   {
-    std::cout << "Not an assembly\n";
+    Message::SendFail ("Syntax error: Not an assembly");
     return 1;
   }
 
@@ -4578,6 +4632,155 @@ static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
   return 0;
 }
 
+//=======================================================================
+//function : VChild
+//purpose  :
+//=======================================================================
+static Standard_Integer VChild (Draw_Interpretor& ,
+                                Standard_Integer theNbArgs,
+                                const char** theArgVec)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
+  {
+    Message::SendFail ("Error: no active viewer");
+    return 1;
+  }
+
+  int toAdd = -1;
+  Handle(AIS_InteractiveObject) aParent;
+  bool hasActions = false;
+  int toInheritTrsf = -1;
+  ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
+  for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anArgIter]);
+    anArg.LowerCase();
+    if (anUpdateTool.parseRedrawMode (anArg))
+    {
+      continue;
+    }
+    else if (anArg == "-add")
+    {
+      toAdd = 1;
+      continue;
+    }
+    else if (anArg == "-remove")
+    {
+      toAdd = 0;
+      continue;
+    }
+    else if (anArg == "-inheritparenttrsf"
+      || anArg == "-inheritparentloc"
+      || anArg == "-inheritparentlocation"
+      || anArg == "-inheritparent"
+      || anArg == "-noinheritparenttrsf"
+      || anArg == "-noinheritparentloc"
+      || anArg == "-noinheritparentlocation"
+      || anArg == "-noinheritparent"
+      || anArg == "-ignoreparenttrsf"
+      || anArg == "-ignoreparentloc"
+      || anArg == "-ignoreparentlocation"
+      || anArg == "-ignoreparent")
+    {
+      bool aVal = true;
+      if (anArgIter + 1 < theNbArgs
+        && ViewerTest::ParseOnOff(theArgVec[anArgIter + 1], aVal))
+      {
+        ++anArgIter;
+      }
+      if (anArg.StartsWith("-no")
+        || anArg.StartsWith("-ignore"))
+      {
+        aVal = !aVal;
+      }
+      toInheritTrsf = aVal ? 1 : 0;
+      continue;
+    }
+
+    Handle(AIS_InteractiveObject) aChild;
+    if (!GetMapOfAIS().Find2 (theArgVec[anArgIter], aChild))
+    {
+      Message::SendFail() << "Syntax error: object '" << theArgVec[anArgIter] << "' is not found";
+      return 1;
+    }
+
+    if (aParent.IsNull())
+    {
+      aParent = aChild;
+    }
+    else if (toAdd == -1)
+    {
+      Message::SendFail ("Syntax error: no action specified");
+      return 1;
+    }
+    else
+    {
+      hasActions = true;
+      if (toAdd == 1)
+      {
+        if(toInheritTrsf == 0)
+          aParent->AddChildWithCurrentTransformation(aChild);
+        else
+          aParent->AddChild (aChild);
+      }
+      else
+      {
+        if (toInheritTrsf == 0)
+          aParent->RemoveChildWithRestoreTransformation(aChild);
+        else
+          aParent->RemoveChild (aChild);
+      }
+    }
+  }
+  if (!hasActions)
+  {
+    Message::SendFail ("Syntax error: not enough arguments");
+    return 1;
+  }
+  return 0;
+}
+
+//=======================================================================
+//function : VParent
+//purpose  :
+//=======================================================================
+static Standard_Integer VParent(Draw_Interpretor&,
+  Standard_Integer theNbArgs,
+  const char** theArgVec)
+{
+  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+  if (aContext.IsNull())
+  {
+    Message::SendFail ("Error: no active viewer");
+    return 1;
+  }
+
+  if (theNbArgs < 2 )
+  {
+    Message::SendFail ("Syntax error: wrong number of arguments");
+    return 1;
+  }
+
+  TCollection_AsciiString aName(theArgVec[1]);
+  Handle(AIS_InteractiveObject) aParent;
+  if (!GetMapOfAIS().Find2(theArgVec[1], aParent))
+  {
+    Message::SendFail() << "Syntax error: object '" << theArgVec[1] << "' is not found";
+    return 1;
+  }
+
+  ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
+  for (Standard_Integer anArgIter = 2; anArgIter < theNbArgs; ++anArgIter)
+  {
+    TCollection_AsciiString anArg(theArgVec[anArgIter]);
+    anArg.LowerCase();
+    if (anArg == "-ignorevisu")
+      aParent->SetPropagateVisualState(Standard_False);
+  }
+  return 0;
+}
+
 //===============================================================================================
 //function : VSetSelectionMode
 //purpose  : vselmode
@@ -4590,7 +4793,7 @@ static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
   if (anAISContext.IsNull())
   {
-    std::cout << "Error: no active Viewer\n";
+    Message::SendFail ("Error: no active Viewer");
     return 1;
   }
 
@@ -4629,7 +4832,7 @@ static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
   if (anObjNames.Size() < 2
   || !ViewerTest::ParseOnOff (anObjNames.Last().ToCString(), toTurnOn))
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
   anObjNames.Remove (anObjNames.Upper());
@@ -4647,7 +4850,7 @@ static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
     }
     else
     {
-      std::cout << "Syntax error: unknown selection mode '" << aSelModeString  << "'\n";
+      Message::SendFail() << "Syntax error: unknown selection mode '" << aSelModeString  << "'";
       return 1;
     }
   }
@@ -4660,7 +4863,7 @@ static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
     GetMapOfAIS().Find2 (aNameIO, anIO);
     if (anIO.IsNull())
     {
-      std::cout << "Syntax error: undefined presentable object " << aNameIO << "\n";
+      Message::SendFail() << "Syntax error: undefined presentable object " << aNameIO;
       return 1;
     }
     aTargetIOs.Append (anIO);
@@ -4692,7 +4895,7 @@ static Standard_Integer VSelectionNext(Draw_Interpretor& /*theDI*/,
 
   if (anAISContext.IsNull())
   {
-    std::cerr << "Call vinit before!" << std::endl;
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4714,7 +4917,7 @@ static Standard_Integer VSelectionPrevious(Draw_Interpretor& /*theDI*/,
 
   if (anAISContext.IsNull())
   {
-    std::cerr << "Call vinit before!" << std::endl;
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4744,7 +4947,7 @@ static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
 
   if (argc != (2 + aPrims->VertexNumberAllocated()))
   {
-    std::cout << "Syntax error: wrong number of arguments\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -4762,7 +4965,7 @@ static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
       if (aShape.IsNull()
        || aShape.ShapeType() != TopAbs_VERTEX)
       {
-        std::cout << "Syntax error: argument " << aName << " must be a point\n";
+        Message::SendFail() << "Syntax error: argument " << aName << " must be a point";
         return 1;
       }
       aPnts[aPntIter] = BRep_Tool::Pnt (TopoDS::Vertex (aShape));
@@ -4772,7 +4975,7 @@ static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
     {
       if (aPnts[aPnt2Iter].IsEqual (aPnts[aPntIter], Precision::Confusion()))
       {
-        std::cout << "Syntax error: points should not be equal\n";
+        Message::SendFail ("Syntax error: points should not be equal");
         return 1;
       }
     }
@@ -4780,7 +4983,13 @@ static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
     aPrims->AddVertex (aPnts[aPntIter]);
   }
 
-  ViewerTest::Display (argv[1], new MyPArrayObject (aPrims));
+  Handle(AIS_InteractiveObject) aPrs = new MyPArrayObject (aPrims);
+  if (!isTri)
+  {
+    aPrs->Attributes()->SetupOwnShadingAspect();
+    aPrs->Attributes()->ShadingAspect()->Aspect()->SetColor (aPrs->Attributes()->LineAspect()->Aspect()->Color());
+  }
+  ViewerTest::Display (argv[1], aPrs);
   return 0;
 }
 
@@ -4796,7 +5005,7 @@ static Standard_Integer VObjZLayer (Draw_Interpretor& di,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    di << argv[0] << "Call 'vinit' before!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -4822,7 +5031,7 @@ static Standard_Integer VObjZLayer (Draw_Interpretor& di,
   GetMapOfAIS().Find2 (aName, anInterObj);
   if (anInterObj.IsNull())
   {
-    std::cout << "Syntax error: object '" << aName << "' is not displayed\n";
+    Message::SendFail() << "Syntax error: object '" << aName << "' is not displayed";
     return 1;
   }
 
@@ -4851,14 +5060,15 @@ static Standard_Integer VPolygonOffset(Draw_Interpretor& /*di*/,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << argv[0] << " Call 'vinit' before!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   if (argc > 2 && argc != 5)
   {
-    std::cout << "Usage : " << argv[0] << " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
-      "without arguments prints the default values" << std::endl;
+    Message::SendFail() << "Syntax error: wrong number of arguments.\n"
+                           "Usage: " << argv[0] << " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
+                           "without arguments prints the default values";
     return 1;
   }
 
@@ -4870,7 +5080,7 @@ static Standard_Integer VPolygonOffset(Draw_Interpretor& /*di*/,
     if (!GetMapOfAIS().Find2 (aName, anInterObj)
       || anInterObj.IsNull())
     {
-      std::cout << "Syntax error: object '" << aName << "' is not displayed\n";
+      Message::SendFail() << "Syntax error: object '" << aName << "' is not displayed";
       return 1;
     }
   }
@@ -4913,113 +5123,7 @@ static Standard_Integer VPolygonOffset(Draw_Interpretor& /*di*/,
   return 0;
 }
 
-//=======================================================================
-//function : VShowFaceBoundaries
-//purpose  : Set face boundaries drawing on/off for ais object
-//=======================================================================
-static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/,
-                                           Standard_Integer argc,
-                                           const char ** argv)
-{
-  Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext ();
-  if (aContext.IsNull ())
-  {
-    std::cout << argv[0] << " Call 'vinit' before!\n";
-    return 1;
-  }
-
-  if ((argc != 3 && argc < 6) || argc > 8)
-  {
-    std::cout << "Usage :\n " << argv[0]
-              << " ObjectName isOn [R G B [LineWidth [LineStyle]]]\n"
-              << "   ObjectName - name of AIS interactive object. \n"
-              << "                if ObjectName = \"\", then set as default\n"
-              << "                settings for all newly displayed objects\n"
-              << "   isOn       - flag indicating whether the boundaries\n"
-              << "                should be turned on or off (can be set\n"
-              << "                to 0 (off) or 1 (on)).\n"
-              << "   R, G, B    - red, green and blue components of boundary\n"
-              << "                color in range (0 - 255).\n"
-              << "                (default is (0, 0, 0)\n"
-              << "   LineWidth  - line width\n"
-              << "                (default is 1)\n"
-              << "   LineStyle  - line fill style :\n"
-              << "                 0 - solid  \n"
-              << "                 1 - dashed \n"
-              << "                 2 - dot    \n"
-              << "                 3 - dashdot\n"
-              << "                 (default is solid)";
-    return 1;
-  }
-
-  TCollection_AsciiString aName (argv[1]);
-
-  Standard_Real aRed   = 0.0;
-  Standard_Real aGreen = 0.0;
-  Standard_Real aBlue  = 0.0;
-  Standard_Real aWidth = 1.0;
-  Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
-  
-  // find object
-  Handle(AIS_InteractiveObject) anInterObj;
-
-  // if name is empty - apply attributes for default aspect
-  if (!aName.IsEmpty ())
-  {
-    if (!GetMapOfAIS().Find2 (aName, anInterObj)
-      || anInterObj.IsNull())
-    {
-      std::cout << "Use 'vdisplay' on " << aName << " before" << std::endl;
-      return 1;
-    }
-  }
-  
-  const Handle(Prs3d_Drawer)& aDrawer = (aName.IsEmpty ()) ?
-    TheAISContext ()->DefaultDrawer () : anInterObj->Attributes ();
-
-  // turn boundaries on/off
-  Standard_Boolean isBoundaryDraw = (Draw::Atoi (argv[2]) == 1);
-  aDrawer->SetFaceBoundaryDraw (isBoundaryDraw);
-  
-  // set boundary line color
-  if (argc >= 6)
-  {
-    // Text color
-    aRed   = Draw::Atof (argv[3])/255.;
-    aGreen = Draw::Atof (argv[4])/255.;
-    aBlue  = Draw::Atof (argv[5])/255.;
-  }
-
-  // set line width
-  if (argc >= 7)
-  {
-    aWidth = (Standard_Real)Draw::Atof (argv[6]);
-  }
-
-  // select appropriate line type
-  if (argc == 8)
-  {
-    if (!ViewerTest::ParseLineType (argv[7], aLineType))
-    {
-      std::cout << "Syntax error: unknown line type '" << argv[7] << "'\n";
-      return 1;
-    }
-  }
-
-  Quantity_Color aColor (aRed, aGreen, aBlue, Quantity_TOC_RGB);
-
-  Handle(Prs3d_LineAspect) aBoundaryAspect = 
-    new Prs3d_LineAspect (aColor, aLineType, aWidth);
-
-  aDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
-
-  TheAISContext()->Redisplay (anInterObj, Standard_True);
-  
-  return 0;
-}
-
 // This class is used for testing markers.
-
 class ViewerTest_MarkersArrayObject : public AIS_InteractiveObject
 {
 
@@ -5126,14 +5230,13 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cerr << "Call 'vinit' before!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
   if (theArgNb < 5)
   {
-    std::cerr << "Usage :\n " << theArgVec[0]
-              << "name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n";
+    Message::SendFail ("Syntax error: wrong number of arguments");
     return 1;
   }
 
@@ -5170,7 +5273,7 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&,
     }
     else
     {
-      std::cerr << "Wrong argument: " << anArg << "\n";
+      Message::SendFail() << "Syntax error: wrong argument '" << anArg << "'";
       return 1;
     }
   }
@@ -5184,7 +5287,7 @@ static Standard_Integer VMarkersTest (Draw_Interpretor&,
     anImage = new Image_AlienPixMap();
     if (!anImage->Load (aFileName))
     {
-      std::cerr << "Could not load image from file '" << aFileName << "'!\n";
+      Message::SendFail() << "Error: could not load image from file '" << aFileName << "'!";
       return 1;
     }
     if (anImage->Format() == Image_Format_Gray)
@@ -5219,7 +5322,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
   // Check arguments
   if (theArgNb < 3)
   {
-    std::cerr << "Error: " << theArgVec[0] << " - invalid syntax\n";
+    Message::SendFail() << "Error: " << theArgVec[0] << " - invalid syntax";
     return 1;
   }
 
@@ -5239,7 +5342,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
 
   Graphic3d_HorizontalTextAlignment aHJustification = Graphic3d_HTA_LEFT;
   Graphic3d_VerticalTextAlignment   aVJustification = Graphic3d_VTA_BOTTOM;
-
+  Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
   for (; anArgIt < theArgNb; ++anArgIt)
   {
     TCollection_AsciiString aParam (theArgVec[anArgIt]);
@@ -5250,7 +5353,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (anArgIt + 3 >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5262,7 +5365,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5282,7 +5385,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong syntax at '" << aParam << "'";
         return 1;
       }
     }
@@ -5290,7 +5393,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5314,7 +5417,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
       }
       else
       {
-        std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong syntax at '" << aParam << "'";
         return 1;
       }
     }
@@ -5322,7 +5425,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5332,7 +5435,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5340,7 +5443,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
       anOption.LowerCase();
       if (!parseFontStyle (anOption, aFontAspect))
       {
-        std::cout << "Error: unknown font aspect '" << anOption << "'.\n";
+        Message::SendFail() << "Error: unknown font aspect '" << anOption << "'";
         return 1;
       }
     }
@@ -5348,17 +5451,23 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
       aFontName = theArgVec[anArgIt];
     }
+    else if (aParam == "-strict")
+    {
+      anArgIt += parseFontStrictLevel (theArgNb  - anArgIt - 1,
+                                       theArgVec + anArgIt + 1,
+                                       aStrictLevel);
+    }
     else if (aParam == "-composite")
     {
       if (++anArgIt >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5368,7 +5477,7 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     {
       if (anArgIt + 6 >= theArgNb)
       {
-        std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
+        Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
         return 1;
       }
 
@@ -5384,14 +5493,14 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
     }
     else
     {
-      std::cerr << "Warning! Unknown argument '" << aParam << "'\n";
+      Message::SendFail() << "Warning! Unknown argument '" << aParam << "'";
     }
   }
 
   aFont.SetCompositeCurveMode (anIsCompositeCurve);
-  if (!aFont.Init (aFontName.ToCString(), aFontAspect, aTextHeight))
+  if (!aFont.FindAndInit (aFontName.ToCString(), aFontAspect, aTextHeight, aStrictLevel))
   {
-    std::cerr << "Font initialization error\n";
+    Message::SendFail ("Error: unable to load Font");
     return 1;
   }
 
@@ -5406,42 +5515,58 @@ static int TextToBRep (Draw_Interpretor& /*theDI*/,
 //function : VFont
 //purpose  : Font management
 //=======================================================================
+struct FontComparator
+{
+  bool operator() (const Handle(Font_SystemFont)& theFontA,
+                   const Handle(Font_SystemFont)& theFontB)
+  {
+    return theFontA->FontKey().IsLess (theFontB->FontKey());
+  }
+};
 
 static int VFont (Draw_Interpretor& theDI,
                   Standard_Integer  theArgNb,
                   const char**      theArgVec)
 {
   Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
-  if (theArgNb < 2)
-  {
-    // just print the list of available fonts
-    Standard_Boolean isFirst = Standard_True;
-    const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
-    for (Font_NListOfSystemFont::Iterator anIter (aFonts); anIter.More(); anIter.Next())
-    {
-      const Handle(Font_SystemFont)& aFont = anIter.Value();
-      if (!isFirst)
-      {
-        theDI << "\n";
-      }
-
-      theDI << aFont->ToString();
-      isFirst = Standard_False;
-    }
-    return 0;
-  }
-
+  bool toPrintList = theArgNb < 2, toPrintNames = false;
+  Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
   {
     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
     TCollection_AsciiString anArgCase (anArg);
     anArgCase.LowerCase();
-    if (anArgIter + 1 < theArgNb
-     && (anArgCase == "-find"
-      || anArgCase == "find"))
+    if (anArgCase == "-strict")
     {
-      Standard_CString aFontName   = theArgVec[++anArgIter];
-      Font_FontAspect  aFontAspect = Font_FA_Undefined;
+      anArgIter += parseFontStrictLevel (theArgNb  - anArgIter - 1,
+                                         theArgVec + anArgIter + 1,
+                                         aStrictLevel);
+    }
+    else if (anArgCase == "-clear")
+    {
+      aMgr->ClearFontDataBase();
+    }
+    else if (anArgCase == "-init")
+    {
+      aMgr->InitFontDataBase();
+    }
+    else if (anArgCase == "-list")
+    {
+      toPrintList = true;
+    }
+    else if (anArgCase == "-names")
+    {
+      toPrintList = true;
+      toPrintNames = true;
+    }
+    else if (anArgIter + 1 < theArgNb
+          && (anArgCase == "-find"
+           || anArgCase == "-findinfo"
+           || anArgCase == "-findall"
+           || anArgCase == "find"))
+    {
+      const TCollection_AsciiString aFontName (theArgVec[++anArgIter]);
+      Font_FontAspect aFontAspect = Font_FA_Undefined;
       if (++anArgIter < theArgNb)
       {
         anArgCase = theArgVec[anArgIter];
@@ -5452,13 +5577,56 @@ static int VFont (Draw_Interpretor& theDI,
         }
       }
 
-      if (Handle(Font_SystemFont) aFont = aMgr->FindFont (aFontName, aFontAspect))
+      const bool toFindAll   = (anArgCase == "-findall");
+      const bool toPrintInfo = (anArgCase == "-findinfo");
+      TCollection_AsciiString aResult;
+      if (toFindAll
+       || aFontName.Search ("*") != -1)
       {
-        theDI << aFont->ToString();
+        const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
+        std::vector<Handle(Font_SystemFont)> aFontsSorted;
+        aFontsSorted.reserve (aFonts.Size());
+        for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
+        {
+          aFontsSorted.push_back (aFontIter.Value());
+        }
+        std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
+        for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
+        {
+          const Handle(Font_SystemFont)& aFont = *aFontIter;
+          const TCollection_AsciiString aCheck = TCollection_AsciiString ("string match -nocase \"") + aFontName + "\" \"" + aFont->FontName() + "\"";
+          if (theDI.Eval (aCheck.ToCString()) == 0
+          && *theDI.Result() != '1')
+          {
+            theDI.Reset();
+            continue;
+          }
+
+          theDI.Reset();
+          if (!aResult.IsEmpty())
+          {
+            aResult += "\n";
+          }
+
+          aResult += toPrintInfo ? aFont->ToString() : aFont->FontName();
+          if (!toFindAll)
+          {
+            break;
+          }
+        }
+      }
+      else if (Handle(Font_SystemFont) aFont = aMgr->FindFont (aFontName, aStrictLevel, aFontAspect))
+      {
+        aResult = toPrintInfo ? aFont->ToString() : aFont->FontName();
+      }
+
+      if (!aResult.IsEmpty())
+      {
+        theDI << aResult;
       }
       else
       {
-        std::cerr << "Error: font '" << aFontName << "' is not found!\n";
+        Message::SendFail() << "Error: font '" << aFontName << "' is not found";
       }
     }
     else if (anArgIter + 1 < theArgNb
@@ -5501,7 +5669,7 @@ static int VFont (Draw_Interpretor& theDI,
       Handle(Font_SystemFont) aFont = aMgr->CheckFont (aFontPath);
       if (aFont.IsNull())
       {
-        std::cerr << "Error: font '" << aFontPath << "' is not found!\n";
+        Message::SendFail() << "Error: font '" << aFontPath << "' is not found!";
         continue;
       }
 
@@ -5516,13 +5684,15 @@ static int VFont (Draw_Interpretor& theDI,
         Handle(Font_SystemFont) aFont2 = new Font_SystemFont (aName);
         if (aFontAspect != Font_FontAspect_UNDEFINED)
         {
-          aFont2->SetFontPath (aFontAspect, aFontPath);
+          aFont2->SetFontPath (aFontAspect, aFontPath, 0);
         }
         else
         {
           for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
           {
-            aFont2->SetFontPath ((Font_FontAspect )anAspectIter, aFont->FontPath ((Font_FontAspect )anAspectIter));
+            aFont2->SetFontPath ((Font_FontAspect )anAspectIter,
+                                 aFont->FontPath ((Font_FontAspect )anAspectIter),
+                                 aFont->FontFaceId ((Font_FontAspect )anAspectIter));
           }
         }
         aFont = aFont2;
@@ -5546,10 +5716,59 @@ static int VFont (Draw_Interpretor& theDI,
       }
       aMgr->SetTraceAliases (toEnable);
     }
+    else if (anArgCase == "-unicodefallback"
+          || anArgCase == "-fallback"
+          || anArgCase == "-touseunicodesubsetfallback")
+    {
+      bool toEnable = true;
+      if (anArgIter + 1 < theArgNb
+       && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable))
+      {
+        ++anArgIter;
+      }
+      Font_FontMgr::ToUseUnicodeSubsetFallback() = toEnable;
+    }
     else
     {
-      std::cerr << "Warning! Unknown argument '" << anArg << "'\n";
+      Message::SendFail() << "Warning! Unknown argument '" << anArg << "'";
+    }
+  }
+
+  if (toPrintList)
+  {
+    // just print the list of available fonts
+    Standard_Boolean isFirst = Standard_True;
+    const Font_NListOfSystemFont aFonts = aMgr->GetAvailableFonts();
+    std::vector<Handle(Font_SystemFont)> aFontsSorted;
+    aFontsSorted.reserve (aFonts.Size());
+    for (Font_NListOfSystemFont::Iterator aFontIter (aFonts); aFontIter.More(); aFontIter.Next())
+    {
+      aFontsSorted.push_back (aFontIter.Value());
+    }
+    std::stable_sort (aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
+    for (std::vector<Handle(Font_SystemFont)>::iterator aFontIter = aFontsSorted.begin(); aFontIter != aFontsSorted.end(); ++aFontIter)
+    {
+      const Handle(Font_SystemFont)& aFont = *aFontIter;
+
+      if (toPrintNames)
+      {
+        if (!isFirst)
+        {
+          theDI << "\n";
+        }
+        theDI << "\"" << aFont->FontName() << "\"";
+      }
+      else
+      {
+        if (!isFirst)
+        {
+          theDI << "\n";
+        }
+        theDI << aFont->ToString();
+      }
+      isFirst = Standard_False;
     }
+    return 0;
   }
 
   return 0;
@@ -5567,7 +5786,7 @@ static int VVertexMode (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5585,8 +5804,8 @@ static int VVertexMode (Draw_Interpretor& theDI,
   {
     if (theArgNum == 2)
     {
-      std::cout << "Error: '-set' option not followed by the mode and optional object name(s)" << std::endl;
-      std::cout << "Type 'help vvertexmode' for usage hints" << std::endl;
+      Message::SendFail ("Error: '-set' option not followed by the mode and optional object name(s)\n"
+                         "Type 'help vvertexmode' for usage hints");
       return 1;
     }
 
@@ -5638,7 +5857,7 @@ static int VVertexMode (Draw_Interpretor& theDI,
   if (theArgNum > 2
   || !GetMapOfAIS().Find2 (aParam, anObject))
   {
-    std::cout << "Error: invalid number of arguments" << std::endl;
+    Message::SendFail ("Syntax error: invalid number of arguments");
     return 1;
   }
 
@@ -5659,7 +5878,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
   if (anAISContext.IsNull())
   {
-    std::cerr << "Error: no active view!\n";
+    Message::SendFail ("Error: no active view!");
     return 1;
   }
 
@@ -5689,7 +5908,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
     case 2  : aCmd = CloudForShape; break;
     case 7  : aCmd = CloudSphere; break;
     default :
-      std::cout << "Error: wrong number of arguments! See usage:\n";
+      Message::SendFail ("Syntax error: wrong number of arguments! See usage:");
       theDI.PrintHelp (theArgs[0]);
       return 1;
   }
@@ -5698,6 +5917,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
   Standard_Boolean toRandColors = Standard_False;
   Standard_Boolean hasNormals   = Standard_True;
   Standard_Boolean isSetArgNorm = Standard_False;
+  Standard_Boolean hasUV        = Standard_False;
   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
   {
     Standard_CString anArg = theArgs[anArgIter];
@@ -5708,7 +5928,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
     {
       if (isSetArgNorm && hasNormals)
       {
-        std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
+        Message::SendFail ("Syntax error: normals can not be enabled with colors at the same time");
         return 1;
       }
       toRandColors = Standard_True;
@@ -5719,7 +5939,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
     {
       if (toRandColors)
       {
-        std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
+        Message::SendFail ("Syntax error: normals can not be enabled with colors at the same time");
         return 1;
       }
       isSetArgNorm = Standard_True;
@@ -5731,9 +5951,27 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
       isSetArgNorm = Standard_True;
       hasNormals   = Standard_False;
     }
+    else if (aFlag == "-uv"
+          || aFlag == "-texels")
+    {
+      hasUV = Standard_True;
+    }
   }
 
   Standard_CString aName = theArgs[1];
+  Graphic3d_ArrayFlags aFlags = Graphic3d_ArrayFlags_None;
+  if (hasNormals)
+  {
+    aFlags |= Graphic3d_ArrayFlags_VertexNormal;
+  }
+  if (toRandColors)
+  {
+    aFlags |= Graphic3d_ArrayFlags_VertexColor;
+  }
+  if (hasUV)
+  {
+    aFlags |= Graphic3d_ArrayFlags_VertexTexel;
+  }
 
   // generate arbitrary set of points
   Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
@@ -5744,7 +5982,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
 
     if (aShape.IsNull())
     {
-      std::cout << "Error: no shape with name '" << aShapeName << "' found\n";
+      Message::SendFail() << "Error: no shape with name '" << aShapeName << "' found";
       return 1;
     }
 
@@ -5762,11 +6000,11 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
     }
     if (aNbPoints < 3)
     {
-      std::cout << "Error: shape should be triangulated!\n";
+      Message::SendFail ("Error: shape should be triangulated");
       return 1;
     }
 
-    anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
+    anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, aFlags);
     for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
     {
       const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
@@ -5812,6 +6050,11 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
         {
           anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter));
         }
+        if (hasUV
+         && aTriangulation->HasUVNodes())
+        {
+          anArrayPoints->SetVertexTexel (anIndexOfPoint, aTriangulation->UVNode (aNodeIter));
+        }
       }
     }
   }
@@ -5827,7 +6070,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
     aDistribution.LowerCase();
     if ( aDistribution != "surface" && aDistribution != "volume" )
     {
-      std::cout << "Error: wrong arguments! See usage:\n";
+      Message::SendFail ("Syntax error: wrong arguments. See usage:");
       theDI.PrintHelp (theArgs[0]);
       return 1;
     }
@@ -5835,7 +6078,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
 
     gp_Pnt aCenter(aCenterX, aCenterY, aCenterZ);
 
-    anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
+    anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, aFlags);
     for (Standard_Integer aPntIt = 0; aPntIt < aNbPoints; ++aPntIt)
     {
       Standard_Real anAlpha   = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
@@ -5860,6 +6103,11 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
       {
         anArrayPoints->SetVertexNormal (anIndexOfPoint, aDir);
       }
+      if (hasUV)
+      {
+        anArrayPoints->SetVertexTexel (anIndexOfPoint, gp_Pnt2d (anAlpha / 2.0 * M_PI,
+                                                                 aBeta   / 2.0 * M_PI));
+      }
     }
   }
 
@@ -5883,7 +6131,7 @@ static int VPriority (Draw_Interpretor& theDI,
   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
   if (aContext.IsNull())
   {
-    std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
 
@@ -5896,8 +6144,8 @@ static int VPriority (Draw_Interpretor& theDI,
     --aNbArgs;
     if (aPriority < 0 || aPriority > 10)
     {
-      std::cout << "Error: the specified display priority value '" << aLastArg
-                << "' is outside the valid range [0..10]" << std::endl;
+      Message::SendFail() << "Syntax error: the specified display priority value '" << aLastArg
+                          << "' is outside the valid range [0..10]";
       return 1;
     }
   }
@@ -5908,7 +6156,7 @@ static int VPriority (Draw_Interpretor& theDI,
 
   if (aNbArgs < 2)
   {
-    std::cout << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Syntax error: wrong number of arguments! See usage:");
     theDI.PrintHelp (theArgs[0]);
     return 1;
   }
@@ -5925,7 +6173,7 @@ static int VPriority (Draw_Interpretor& theDI,
     GetMapOfAIS().Find2 (aName, anIObj);
     if (anIObj.IsNull())
     {
-      std::cout << "Error: the object '" << theArgs[1] << "' is not displayed" << std::endl;
+      Message::SendFail() << "Error: the object '" << theArgs[1] << "' is not displayed";
       return 1;
     }
 
@@ -6024,12 +6272,12 @@ static int VNormals (Draw_Interpretor& theDI,
   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
   if (aContext.IsNull())
   {
-    std::cout << "Error: no view available, call 'vinit' before!\n";
+    Message::SendFail ("Error: no active viewer");
     return 1;
   }
   else if (theArgNum < 2)
   {
-    std::cout << "Error: wrong number of arguments! See usage:\n";
+    Message::SendFail ("Syntax error: wrong number of arguments. See usage:");
     theDI.PrintHelp (theArgs[0]);
     return 1;
   }
@@ -6040,7 +6288,7 @@ static int VNormals (Draw_Interpretor& theDI,
   Standard_Boolean isOn = Standard_True;
   if (aShape.IsNull())
   {
-    std::cout << "Error: shape with name '" << aShapeName << "' is not found\n";
+    Message::SendFail() << "Error: shape with name '" << aShapeName << "' is not found";
     return 1;
   }
 
@@ -6076,7 +6324,7 @@ static int VNormals (Draw_Interpretor& theDI,
       aLength = anArgIter < theArgNum ? Draw::Atof (theArgs[anArgIter]) : 0.0;
       if (Abs (aLength) <= gp::Resolution())
       {
-        std::cout << "Syntax error: length should not be zero\n";
+        Message::SendFail ("Syntax error: length should not be zero");
         return 1;
       }
     }
@@ -6097,7 +6345,7 @@ static int VNormals (Draw_Interpretor& theDI,
       aNbAlongU = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
       if (aNbAlongU < 1)
       {
-        std::cout << "Syntax error: NbAlongU should be >=1\n";
+        Message::SendFail ("Syntax error: NbAlongU should be >=1");
         return 1;
       }
     }
@@ -6108,7 +6356,7 @@ static int VNormals (Draw_Interpretor& theDI,
       aNbAlongV = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
       if (aNbAlongV < 1)
       {
-        std::cout << "Syntax error: NbAlongV should be >=1\n";
+        Message::SendFail ("Syntax error: NbAlongV should be >=1");
         return 1;
       }
     }
@@ -6120,13 +6368,13 @@ static int VNormals (Draw_Interpretor& theDI,
       aNbAlongV = aNbAlongU;
       if (aNbAlongU < 1)
       {
-        std::cout << "Syntax error: NbAlong should be >=1\n";
+        Message::SendFail ("Syntax error: NbAlong should be >=1");
         return 1;
       }
     }
     else
     {
-      std::cout << "Syntax error: unknwon argument '" << aParam << "'\n";
+      Message::SendFail() << "Syntax error: unknown argument '" << aParam << "'";
       return 1;
     }
   }
@@ -6238,9 +6486,11 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     __FILE__,VAxisBuilder,group);
 
   theCommands.Add("vpoint",
-    "vpoint  PointName [Xa] [Ya] [Za] "
-    "\n\t\t: Creates a point from coordinates. If the values are not defined,"
-    "\n\t\t: a point is created by interactive selection of a vertice or an edge (in the center of the edge).",
+    "vpoint name [X Y [Z]] [-2d] [-nosel]"
+    "\n\t\t: Creates a point from coordinates."
+    "\n\t\t: If the values are not defined, a point is created from selected vertex or edge (center)."
+    "\n\t\t:  -2d    defines on-screen 2D point from top-left window corner"
+    "\n\t\t:  -nosel creates non-selectable presentation",
     __FILE__,VPointBuilder,group);
 
   theCommands.Add("vplane",
@@ -6307,6 +6557,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    "\n\t\t: [-noupdate]"
                    "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]"
                    "\n\t\t: [-flipping]"
+                   "\n\t\t: [-ownanchor {0|1}=1]"
                    "\n\t\t: Display text label at specified position.",
     __FILE__, VDrawText, group);
 
@@ -6325,6 +6576,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
       "\n\t\t:   [-setLocation X Y [Z]]"
       "\n\t\t:   [-setRotation QX QY QZ QW]"
       "\n\t\t:   [-setScale [X Y Z] scale]"
+      "\n\t\t:   [-inheritParentTrsf {on|off}]"
       "\n\t\t: Object local transformation management:"
       "\n\t\t:   -reset       reset transformation to identity"
       "\n\t\t:   -translate   translate object"
@@ -6333,12 +6585,24 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
       "\n\t\t:   -mirror      applies mirror   to local transformation"
       "\n\t\t:   -setLocation assign object location"
       "\n\t\t:   -setRotation assign object rotation (quaternion)"
-      "\n\t\t:   -setScale    assign object scale factor",
+      "\n\t\t:   -setScale    assign object scale factor"
+      "\n\t\t:   -inheritParentTrsf option to inherit parent"
+      "\n\t\t:                transformation or not (ON by default)",
         __FILE__, VSetLocation, group);
   theCommands.Add ("vsetlocation",
                    "alias for vlocation",
         __FILE__, VSetLocation, group);
-
+  theCommands.Add ("vchild",
+                   "vchild parent [-add] [-remove] [-ignoreParentTrsf {0|1}] child1 [child2] [...]"
+      "\n\t\t: Command for testing low-level presentation connections."
+      "\n\t\t: vconnect command should be used instead.",
+        __FILE__, VChild, group);
+  theCommands.Add("vparent",
+    "vparent parent [-ignoreVisu]"
+    "\n\t\t: Command for testing object properties as parent in the hierarchy."
+    "\n\t\t: Arguments:"
+    "\n\t\t:   -ignoreVisu do not propagate the visual state (display/erase/color) to children objects",
+    __FILE__, VParent, group);
   theCommands.Add ("vcomputehlr",
                 "vcomputehlr shapeInput hlrResult [-algoType {algo|polyAlgo}=polyAlgo]"
       "\n\t\t:   [eyeX eyeY eyeZ dirX dirY dirZ upX upY upZ]"
@@ -6436,12 +6700,6 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     "vpolygonoffset : [object [mode factor units]] - sets/gets polygon offset parameters for an object, without arguments prints the default values",
     __FILE__, VPolygonOffset, group);
 
-  theCommands.Add ("vshowfaceboundary",
-    "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]]"
-    "- turns on/off drawing of face boundaries for ais object "
-    "and defines boundary line style.",
-    __FILE__, VShowFaceBoundary, group);
-
   theCommands.Add ("vmarkerstest",
                    "vmarkerstest: name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n",
                    __FILE__, VMarkersTest, group);
@@ -6453,13 +6711,19 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    "\n\t\t: [-valign {top|center|bottom|topfirstline}=bottom}]"
                    "\n\t\t: [-height height=16]"
                    "\n\t\t: [-aspect {regular|bold|italic|boldItalic}=regular]"
-                   "\n\t\t: [-font font=Courier]"
+                   "\n\t\t: [-font font=Courier] [-strict {strict|aliases|any}=any]"
                    "\n\t\t: [-composite {on|off}=off]"
                    "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]",
                    __FILE__, TextToBRep, group);
   theCommands.Add ("vfont",
                             "vfont [-add pathToFont [fontName] [regular,bold,italic,boldItalic=undefined] [singleStroke]]"
-                   "\n\t\t:        [-find fontName [regular,bold,italic,boldItalic=undefined]] [-verbose {on|off}]",
+                   "\n\t\t:        [-strict {any|aliases|strict}] [-find fontName [regular,bold,italic,boldItalic=undefined]] [-verbose {on|off}]"
+                   "\n\t\t:        [-findAll fontNameMask] [-findInfo fontName]"
+                   "\n\t\t:        [-unicodeFallback {on|off}]"
+                   "\n\t\t:        [-clear] [-init] [-list] [-names]"
+                   "\n\t\t: Work with font registry - register font, list available fonts, find font."
+                   "\n\t\t: -findAll  is same as -find, but can print more than one font when mask is passed."
+                   "\n\t\t: -findInfo is same as -find, but prints complete font information instead of family name.",
                    __FILE__, VFont, group);
 
   theCommands.Add ("vvertexmode",
@@ -6471,12 +6735,12 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
                    __FILE__, VVertexMode, group);
 
   theCommands.Add ("vpointcloud",
-                   "vpointcloud name shape [-randColor] [-normals] [-noNormals]"
+                   "vpointcloud name shape [-randColor] [-normals] [-noNormals] [-uv]"
                    "\n\t\t: Create an interactive object for arbitary set of points"
                    "\n\t\t: from triangulated shape."
                    "\n"
                    "vpointcloud name x y z r npts {surface|volume}\n"
-                   "            ... [-randColor] [-normals] [-noNormals]"
+                   "            ... [-randColor] [-normals] [-noNormals] [-uv]"
                    "\n\t\t: Create arbitrary set of points (npts) randomly distributed"
                    "\n\t\t: on spheric surface or within spheric volume (x y z r)."
                    "\n\t\t:"