diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp
index 37a7e81a2558605740465c66f6deedcd246cf19d..6535b34831b0464b21c6f1c172b1c366355945cc 100644
--- a/pub/src/expr.cpp
+++ b/pub/src/expr.cpp
@@ -435,7 +435,7 @@ CTree::CTree( char _typ )
         typ = _DUMMY;
     } else if ( _typ=='d' ) { // Dirac delta function centered at 0
         typ = _DIRAC;
-        arg[0] = PTree( new CTree( 0.0 ) );
+        arg[0] = PTree( new CNodeVal( 0.0 ) );
         narg = 1;
     } else
         throw string( "invalid tree type in char-constructor" );
@@ -454,7 +454,7 @@ CTree::CTree( char _typ, const PTree& a0 )
     } else if ( _typ=='c' ) {
         typ = _CONV;
         arg[0] = a0;
-        arg[1] = PTree( new CTree( 0.0 ) );
+        arg[1] = PTree( new CNodeVal( 0.0 ) );
         narg = 2;
     } else
         throw string( "invalid tree type in char-constructor" );
@@ -536,26 +536,37 @@ CTree::CTree( PRgr& _rgr )
 uint CTree::npar() const
 {
     uint np=0;
-    npar_exec( &np );
+    npar_exec( &np ); // implemented with pointer argument to allow recursion
     return np;
 }
 
-//! Implementation with pointer argument to allow recursion.
+//! Implementation 
 
-void CTree::npar_exec( uint *np ) const
+void CNodeFun::npar_exec( uint *np ) const
 {
-    if      ( typ == _OP || typ == _CONV || typ == _DIRAC )
-        for ( uint iarg=0; iarg<narg; ++iarg )
-            arg[iarg]->npar_exec( np );
-    else if ( typ == _VAL || typ == _DUMMY || typ == _CEV || typ == _RGR )
-        ; // do nothing
-    else if ( typ == _REF ) {
-        if ( ref->typ==CRef::_CP )
-            *np = max (*np, ref->num+1);
-    } else
-        throw string( "BUG: npar(UNDEF)" );
+    for ( uint iarg=0; iarg<narg; ++iarg )
+        arg[iarg]->npar_exec( np );
+}
+
+void CNodeConv::npar_exec( uint *np ) const
+{
+    for ( uint iarg=0; iarg<narg; ++iarg )
+        arg[iarg]->npar_exec( np );
+}
+
+void CNodeDirac::npar_exec( uint *np ) const
+{
+    for ( uint iarg=0; iarg<narg; ++iarg )
+        arg[iarg]->npar_exec( np );
 }
 
+void CNodeIva::npar_exec( uint *np ) const
+{
+    if ( ref->typ==CRef::_CP )
+        *np = max( *np, ref->num+1 );
+}
+
+
 //! Does the result depend on k?
 
 bool CTree::k_dependent() const
diff --git a/pub/src/expr.h b/pub/src/expr.h
index 176e8fdb36571d599100bc16dfef920689ca76ea..9cd02cc4486a5ef17e3803b7fb1e81adc076edfc 100644
--- a/pub/src/expr.h
+++ b/pub/src/expr.h
@@ -95,6 +95,7 @@ class CTree {
         _DIRAC  // Dirac delta function
     };
     TreeTyp typ;
+ protected:
     static const uint maxarg=3;
     PTree arg[maxarg];
     uint narg;
@@ -103,11 +104,13 @@ class CTree {
     PRef ref;
     PRgr rgr;
 
+ private:
     void tree_op   ( CResult& ret, const CContext& ctx ) const;
     void tree_conv ( CResult& ret, const CContext& ctx ) const;
     void tree_cev  ( CResult& ret, const CContext& ctx ) const;
 
-    void npar_exec( uint *np ) const;
+ public:
+    virtual void npar_exec( uint *np ) const = 0;
     void kdep_exec( bool *kd ) const;
 
  public:
@@ -144,6 +147,8 @@ class CTree {
 //! Function/operator node.
 
 class CNodeFun: public CTree {
+ private:
+    void npar_exec( uint *np ) const;
  public:
     CNodeFun( const class CFunc *f_in, PTree a0 );
     CNodeFun( const class CFunc *f_in, PTree a0, PTree a1 );
@@ -153,6 +158,8 @@ class CNodeFun: public CTree {
 //! End node with fixed numeric value.
 
 class CNodeVal: public CTree {
+ private:
+    void npar_exec( uint *np ) const {;}
  public:
     CNodeVal( double _val );
 };
@@ -160,6 +167,8 @@ class CNodeVal: public CTree {
 //! Indexed variable node.
 
 class CNodeIva: public CTree {
+ private:
+    void npar_exec( uint *np ) const;
  public:
     CNodeIva( PRef& _ref );
 };
@@ -167,6 +176,8 @@ class CNodeIva: public CTree {
 //! Register reference node.
 
 class CNodeRgr: public CTree {
+ private:
+    void npar_exec( uint *np ) const {;}
  public:
     CNodeRgr( PRgr& _rgr );
 };
@@ -174,6 +185,8 @@ class CNodeRgr: public CTree {
 //! Function argument (t) node.
 
 class CNodeArg: public CTree {
+ private:
+    void npar_exec( uint *np ) const {;}
  public:
     CNodeArg();
 };
@@ -181,6 +194,8 @@ class CNodeArg: public CTree {
 //! Curve evaluation node.
 
 class CNodeCev: public CTree {
+ private:
+    void npar_exec( uint *np ) const {;}
  public:
     CNodeCev( PRef& _ref, PTree a0 );
 };
@@ -193,6 +208,8 @@ class CNodeCev: public CTree {
 //! Convoluted function node.
 
 class CNodeConv: public CTree { // CNodeWithResol {
+ private:
+    void npar_exec( uint *np ) const;
  public:
     CNodeConv( const PTree& a0 );
     CNodeConv( const PTree& a0, const PTree& a1 );
@@ -201,6 +218,8 @@ class CNodeConv: public CTree { // CNodeWithResol {
 //! Dirac's delta function node, to request a copy of the resolution function.
 
 class CNodeDirac: public CTree { // CNodeWithResol {
+ private:
+    void npar_exec( uint *np ) const;
  public:
     CNodeDirac();
     CNodeDirac( const PTree& a0 );