diff --git a/AUTHORS b/AUTHORS
index 5c62ad9fef602688a7a85d393e70c9bebc5d195c..291539d83ced3eae7f352e6523abe35f2488a4e3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,8 +9,9 @@ documentation, other elements
 
 Robert Morris
 rtm@lcs.mit.edu
-design, Ethernet elements, IP elements, Linux kernel module elements,
-radio elements, Linux kernel patches, other elements
+design, Ethernet elements, IP elements, Linux kernel module elements, radio
+elements, Linux kernel patches, IP router configuration, element
+documentation, other elements
 
 Alex Snoeren
 snoeren@lcs.mit.edu
diff --git a/doc/Element.3 b/doc/Element.3
new file mode 100644
index 0000000000000000000000000000000000000000..197ac17b3a88745724139f6da21b0e7e1019b72e
--- /dev/null
+++ b/doc/Element.3
@@ -0,0 +1,120 @@
+.\" -*- mode: nroff -*-
+.ds E " \-\- 
+.if t .ds E \(em
+.de Sp
+.if n .sp
+.if t .sp 0.4
+..
+.de Es
+.Sp
+.RS 5
+.nf
+..
+.de Ee
+.fi
+.RE
+.PP
+..
+.de Rs
+.RS
+.Sp
+..
+.de Re
+.Sp
+.RE
+..
+.TH ELEMENT 3 "19/Oct/1999" "Version \*V"
+.SH NAME
+Element \- Click superclass for elements
+'
+.SH DESCRIPTION
+'
+The C++ class Element is the superclass for all Click elements. This manual
+page describes its operations\*Especifically, the operations that an author
+of an Element subclass might use.
+'
+.SH "INPUT AND OUTPUT PORTS"
+.TP 5
+.PD 0
+.BR "int ninputs() const"
+.TP
+.BR "int noutputs() const"
+Returns the number of input or output ports.
+'
+.Sp
+.TP
+.BR "const Connection &input(" "int \fIport_number" ") const"
+.TP
+.BR "const Connection &output(" "int \fIport_number" ") const"
+Returns a Connection object corresponding to the given input or output
+port. See below for more on Connection objects.
+'
+.Sp
+.TP
+.BR "void set_ninputs(" "int \fInumber_of_ports" ")"
+.TP
+.BR "void set_noutputs(" "int \fInumber_of_ports" ")"
+Sets the number of input or output ports. Any newly created ports are
+unconnected.
+'
+.Sp
+.TP
+.BR "void add_input()"
+.TP
+.BR "void add_output()"
+Adds a single input or output port.
+'
+.Sp
+.TP
+.BR "virtual void notify_ninputs(" "int \fInumber_of_ports_used" ")"
+.TP
+.BR "virtual void notify_noutputs(" "int \fInumber_of_ports_used" ")"
+Called on every element during Router initialization. The parameters are
+the number of that element's input and output ports that are used in the
+router configuration. This is one more than the maximum input or output
+port number that appears in a connection. Elements often react to these
+calls by creating or destroying ports, depending on whether they are needed
+in the router configuration.
+'
+.PD
+'
+.SH "CONNECTIONS"
+'
+.PD 0
+.TP
+.BR "operator bool() const"
+'
+.Sp
+.TP
+.BR "bool allowed() const"
+'
+.Sp
+.TP
+.BR "void push(" "Packet *\fIp" ") const"
+'
+.Sp
+.TP
+.BR "Packet *pull() const"
+'
+.Sp
+.TP
+.BR "Element *element() const"
+'
+.Sp
+.TP
+.BR "int port() const"
+.PD
+'
+.SH "SEE ALSO"
+click(5), elements(n)
+'
+.SH AUTHOR
+.na
+Eddie Kohler, eddietwo@lcs.mit.edu
+.br
+John Jannotti, jj@lcs.mit.edu
+.br
+Robert Morris, rtm@lcs.mit.edu
+.br
+http://www.pdos.lcs.mit.edu/click/
+'
diff --git a/elements/etherswitch/spantree.cc b/elements/etherswitch/spantree.cc
index 5b891c68f5dbc986ac10bd086dd403b2442161e0..78a85aec563adf9b86d2605cf39ae653dd6833c2 100644
--- a/elements/etherswitch/spantree.cc
+++ b/elements/etherswitch/spantree.cc
@@ -38,16 +38,16 @@ EtherSpanTree::clone() const
 }
 
 void
-EtherSpanTree::notify_inputs(int n) {
-  add_inputs(n - ninputs());
-  // the rest is redundant with notify_outputs below
+EtherSpanTree::notify_ninputs(int n) {
+  set_ninputs(n);
+  // the rest is redundant with notify_noutputs below
   _port.resize(n);
 }
 
 void
-EtherSpanTree::notify_outputs(int n) {
-  add_outputs(n - noutputs());
-  // the rest is redundant with notify_inputs above
+EtherSpanTree::notify_noutputs(int n) {
+  set_noutputs(n);
+  // the rest is redundant with notify_ninputs above
   _port.resize(n);
 }
 
diff --git a/elements/etherswitch/spantree.hh b/elements/etherswitch/spantree.hh
index 090923b53ba62b709345999435fe8faa32deb608..0173dcd3b51487bd47ed8fc7ccec0c5bde3743cc 100644
--- a/elements/etherswitch/spantree.hh
+++ b/elements/etherswitch/spantree.hh
@@ -16,8 +16,8 @@ public:
   Processing default_processing() const		{ return PUSH; }
   EtherSpanTree* clone() const;
   
-  void notify_inputs(int);
-  void notify_outputs(int);
+  void notify_ninputs(int);
+  void notify_noutputs(int);
   
   int configure(const String &, ErrorHandler *);
   int initialize(ErrorHandler *);
diff --git a/elements/etherswitch/switch.cc b/elements/etherswitch/switch.cc
index 24a78bd1ec0965a6c4fe12e6b4caa3af2c5eda0b..ddc9b37809c2fcd471a21ea9ae85f3c85b0f765b 100644
--- a/elements/etherswitch/switch.cc
+++ b/elements/etherswitch/switch.cc
@@ -34,6 +34,18 @@ EtherSwitch::~EtherSwitch()
 {
 }
 
+void
+EtherSwitch::notify_ninputs(int n)
+{
+  set_ninputs(n);
+}
+
+void
+EtherSwitch::notify_noutputs(int n)
+{
+  set_noutputs(n);
+}
+
 Bitvector
 EtherSwitch::forward_flow(int i) const
 {
diff --git a/elements/etherswitch/switch.hh b/elements/etherswitch/switch.hh
index 0e16d3d1dd485e001671bfbffbcd60ce99a63954..5dafa35998e8d08e1716d7e91d58cb2f466d83f7 100644
--- a/elements/etherswitch/switch.hh
+++ b/elements/etherswitch/switch.hh
@@ -4,7 +4,7 @@
 #include "etheraddress.hh"
 #include "hashmap.hh"
 
-class EtherSwitch : public UnlimitedElement {
+class EtherSwitch : public Element {
   
  public:
   
@@ -14,8 +14,8 @@ class EtherSwitch : public UnlimitedElement {
   
   const char *class_name() const		{ return "EtherSwitch"; }
   Processing default_processing() const	{ return PUSH; }
-  bool unlimited_inputs() const			{ return true; }
-  bool unlimited_outputs() const		{ return true; }
+  void notify_ninputs(int);
+  void notify_noutputs(int);
   Bitvector forward_flow(int) const;
   Bitvector backward_flow(int) const;
   void push(int port, Packet* p);
diff --git a/elements/ip/checkipheader.cc b/elements/ip/checkipheader.cc
index 9edb44f5fe3d4e693531f8cd02be440b1ae0916a..472da04200419b529c49afbdbd5662c1861bd74a 100644
--- a/elements/ip/checkipheader.cc
+++ b/elements/ip/checkipheader.cc
@@ -42,10 +42,9 @@ CheckIPHeader::clone() const
 }
 
 void
-CheckIPHeader::notify_outputs(int n)
+CheckIPHeader::notify_noutputs(int n)
 {
-  n = (n >= 2 ? 2 : 1);
-  add_outputs(n - noutputs());
+  set_noutputs(n < 2 ? 1 : 2);
 }
 
 void
diff --git a/elements/ip/checkipheader.hh b/elements/ip/checkipheader.hh
index 491a3da41939e79901573715548f8ebc344d9924..21618662efb72d8af8cebc7afc35854f0a6d82ed 100644
--- a/elements/ip/checkipheader.hh
+++ b/elements/ip/checkipheader.hh
@@ -37,7 +37,7 @@ class CheckIPHeader : public Element {
   ~CheckIPHeader();
   
   const char *class_name() const		{ return "CheckIPHeader"; }
-  void notify_outputs(int);
+  void notify_noutputs(int);
   void processing_vector(Vector<int> &, int, Vector<int> &, int) const;
   int configure(const String &, ErrorHandler *);
   
diff --git a/elements/ip/decipttl.cc b/elements/ip/decipttl.cc
index 7f7182d1f3588439f001246c5b58cca39121ffa6..3b4010bc3ca3cd244aceebfcd6cefa7aa32ee23e 100644
--- a/elements/ip/decipttl.cc
+++ b/elements/ip/decipttl.cc
@@ -29,12 +29,11 @@ DecIPTTL::~DecIPTTL()
 }
 
 void
-DecIPTTL::notify_outputs(int n)
+DecIPTTL::notify_noutputs(int n)
 {
   // allow 2 outputs -- then packet is pushed onto 2d output instead of
   // dropped
-  n = (n >= 2 ? 2 : 1);
-  add_outputs(n - noutputs());
+  set_noutputs(n < 2 ? 1 : 2);
 }
 
 void
diff --git a/elements/ip/decipttl.hh b/elements/ip/decipttl.hh
index b7aabc391133f1026251dba3b5dd360c31b8e7cf..ddfe15fe31a039df1653572415e8091296b0d187 100644
--- a/elements/ip/decipttl.hh
+++ b/elements/ip/decipttl.hh
@@ -37,7 +37,7 @@ class DecIPTTL : public Element {
   ~DecIPTTL();
   
   const char *class_name() const		{ return "DecIPTTL"; }
-  void notify_outputs(int);
+  void notify_noutputs(int);
   void processing_vector(Vector<int> &, int, Vector<int> &, int) const;
   
   int drops()					{ return _drops; }
diff --git a/elements/ip/ipfragmenter.cc b/elements/ip/ipfragmenter.cc
index 1f86e70ab26823c0ad1cfbdd5aff65fed037a2b9..73147fb69ba853115eca2bb192abbe1837501d7b 100644
--- a/elements/ip/ipfragmenter.cc
+++ b/elements/ip/ipfragmenter.cc
@@ -33,12 +33,11 @@ IPFragmenter::~IPFragmenter()
 }
 
 void
-IPFragmenter::notify_outputs(int n)
+IPFragmenter::notify_noutputs(int n)
 {
   // allow 2 outputs -- then packet is pushed onto 2d output instead of
   // dropped
-  n = (n >= 2 ? 2 : 1);
-  add_outputs(n - noutputs());
+  set_noutputs(n < 2 ? 1 : 2);
 }
 
 IPFragmenter *
diff --git a/elements/ip/ipfragmenter.hh b/elements/ip/ipfragmenter.hh
index a50ac0a3b4bf7e430989b466bb3b806b2d9eceb1..06b06b9855b7df0ca399608dd515841640c2a2b6 100644
--- a/elements/ip/ipfragmenter.hh
+++ b/elements/ip/ipfragmenter.hh
@@ -43,7 +43,7 @@ class IPFragmenter : public Element {
   
   const char *class_name() const		{ return "IPFragmenter"; }
   int configure(const String &, ErrorHandler *);
-  void notify_outputs(int);
+  void notify_noutputs(int);
   Processing default_processing() const	{ return PUSH; }
   
   int drops()					{ return _drops; }
diff --git a/elements/ip/ipgwoptions.cc b/elements/ip/ipgwoptions.cc
index 1e6142447d7455bb7d233ce09fe0b78f7eb1b5fc..1e3aa13fd9840402bedfce1f5e403e042d89db89 100644
--- a/elements/ip/ipgwoptions.cc
+++ b/elements/ip/ipgwoptions.cc
@@ -45,12 +45,11 @@ IPGWOptions::configure(const String &conf, ErrorHandler *errh)
 }
 
 void
-IPGWOptions::notify_outputs(int n)
+IPGWOptions::notify_noutputs(int n)
 {
   // allow 2 outputs -- then packet is pushed onto 2d output instead of
   // dropped
-  n = (n >= 2 ? 2 : 1);
-  add_outputs(n - noutputs());
+  set_noutputs(n < 2 ? 1 : 2);
 }
 
 void
diff --git a/elements/ip/ipgwoptions.hh b/elements/ip/ipgwoptions.hh
index c851ea4cde9ced2436057d9ff76cb5cb966ff631..16b015c4a5e49cc95bbd80036b3710a98bff6e41 100644
--- a/elements/ip/ipgwoptions.hh
+++ b/elements/ip/ipgwoptions.hh
@@ -42,7 +42,7 @@ class IPGWOptions : public Element {
   
   const char *class_name() const		{ return "IPGWOptions"; }
   int configure(const String &, ErrorHandler *);
-  void notify_outputs(int);
+  void notify_noutputs(int);
   void processing_vector(Vector<int> &, int, Vector<int> &, int) const;
   IPGWOptions *clone() const;
   void add_handlers(HandlerRegistry *fcr);
diff --git a/elements/ip/lookupiproutelinux.cc b/elements/ip/lookupiproutelinux.cc
index 49d56256176639a58bba7796d2cc9860284ddf08..c6e4927540a685c27718936a063333b380305aba 100644
--- a/elements/ip/lookupiproutelinux.cc
+++ b/elements/ip/lookupiproutelinux.cc
@@ -51,7 +51,7 @@ LookupIPRouteLinux::configure(const String &conf, ErrorHandler *)
 {
   cp_argvec(conf, _out2devname);
   _nout = _out2devname.size();
-  add_outputs(_nout + 1);
+  set_noutputs(_nout + 1);
   return 0;
 }
 
diff --git a/elements/standard/classifier.cc b/elements/standard/classifier.cc
index b5274376a65e30586fcfaaad23126378f4f34d7e..2b01c795550a463b693f4a30d356eca46366d82f 100644
--- a/elements/standard/classifier.cc
+++ b/elements/standard/classifier.cc
@@ -226,14 +226,8 @@ print_spread(Classifier::Spread &s)
 // CLASSIFIER ITSELF
 //
 
-Classifier::Classifier(int slots = 0)
-  : Element(1, slots)
-{
-}
-
-Classifier::Classifier(const Classifier &f)
-  : Element(1, f.noutputs()), _exprs(f._exprs),
-    _output_everything(f._output_everything), _safe_length(f._safe_length)
+Classifier::Classifier()
+  : Element(1, 0)
 {
 }
 
@@ -244,7 +238,7 @@ Classifier::~Classifier()
 Classifier *
 Classifier::clone() const
 {
-  return new Classifier(*this);
+  return new Classifier;
 }
 
 //
@@ -541,7 +535,7 @@ Classifier::configure(const String &conf, ErrorHandler *errh)
 {
   Vector<String> args;
   cp_argvec(conf, args);
-  add_outputs(args.size());
+  set_noutputs(args.size());
   
   _output_everything = -1;
   int FAIL = -noutputs();
diff --git a/elements/standard/classifier.hh b/elements/standard/classifier.hh
index 681d05a07a8ddb17df3920968c4765a6f892b9e1..52fea5486f7d40f6814b915eaae39a0f6f90c598 100644
--- a/elements/standard/classifier.hh
+++ b/elements/standard/classifier.hh
@@ -96,12 +96,11 @@ class Classifier : public Element {
   
  public:
   
-  Classifier(int slots = 0);
-  Classifier(const Classifier &);
+  Classifier();
   ~Classifier();
   
   const char *class_name() const		{ return "Classifier"; }
-  Processing default_processing() const	{ return PUSH; }
+  Processing default_processing() const		{ return PUSH; }
   
   Classifier *clone() const;
   int configure(const String &, ErrorHandler *);
diff --git a/elements/standard/idle.cc b/elements/standard/idle.cc
index f7d512dcf0d1e1db7f0741e644b3fa1e5232c900..43944907c100db0d92ae76a92eee9890113ce72c 100644
--- a/elements/standard/idle.cc
+++ b/elements/standard/idle.cc
@@ -26,17 +26,15 @@ Idle::~Idle()
 }
 
 void
-Idle::notify_inputs(int n)
+Idle::notify_ninputs(int n)
 {
-  n = (n > 1 ? 1 : n);
-  add_inputs(n - ninputs());
+  set_ninputs(n);
 }
 
 void
-Idle::notify_outputs(int n)
+Idle::notify_noutputs(int n)
 {
-  n = (n > 1 ? 1 : n);
-  add_outputs(n - noutputs());
+  set_noutputs(n);
 }
 
 Bitvector
@@ -66,16 +64,24 @@ Idle::pull(int)
 bool
 Idle::wants_packet_upstream() const
 {
-  return input_is_pull(0);
+  for (int i = 0; i < ninputs(); i++)
+    if (input_is_pull(i))
+      return true;
+  return false;
 }
 
 void
 Idle::run_scheduled()
 {
-  if (Packet *p = input(0).pull()) {
-    p->kill();
+  bool got_any = false;
+  for (int i = 0; i < ninputs(); i++)
+    if (input_is_pull(i))
+      if (Packet *p = input(i).pull()) {
+	p->kill();
+	got_any = true;
+      }
+  if (got_any)
     schedule_tail();
-  }
 }
 
 EXPORT_ELEMENT(Idle)
diff --git a/elements/standard/idle.hh b/elements/standard/idle.hh
index 9f31d28949267ab257ce5710b078def715c66fb0..5dd78012d1245a9fb769644367e115e4650930fa 100644
--- a/elements/standard/idle.hh
+++ b/elements/standard/idle.hh
@@ -19,8 +19,8 @@ class Idle : public Element {
   ~Idle();
   
   const char *class_name() const		{ return "Idle"; }
-  void notify_inputs(int);
-  void notify_outputs(int);
+  void notify_ninputs(int);
+  void notify_noutputs(int);
   Processing default_processing() const	{ return AGNOSTIC; }
   Bitvector forward_flow(int) const;
   Bitvector backward_flow(int) const;
diff --git a/elements/standard/meter.cc b/elements/standard/meter.cc
index 956707906150036766e03065f2bc11b34bc1323d..df812951e25a2ebd2584e774cc60317bc3a28ef0 100644
--- a/elements/standard/meter.cc
+++ b/elements/standard/meter.cc
@@ -74,7 +74,7 @@ Meter::configure(const String &conf, ErrorHandler *errh)
     _nmeters = vals.size();
   }
 
-  add_outputs(_nmeters + 1 - noutputs());
+  set_noutputs(_nmeters + 1);
   return 0;
 }
 
diff --git a/elements/standard/randomlossage.cc b/elements/standard/randomlossage.cc
index a135081c735130ffd736b01db6f24cffed11b03a..9b57e899c979b53d78cebcee13be7de548de5a6a 100644
--- a/elements/standard/randomlossage.cc
+++ b/elements/standard/randomlossage.cc
@@ -29,10 +29,9 @@ RandomLossage::clone() const
 }
 
 void
-RandomLossage::notify_outputs(int n)
+RandomLossage::notify_noutputs(int n)
 {
-  n = (n >= 2 ? 2 : 1);
-  add_outputs(n - noutputs());
+  set_noutputs(n < 2 ? 1 : 2);
 }
 
 void
diff --git a/elements/standard/randomlossage.hh b/elements/standard/randomlossage.hh
index c86edae6914e5c2bb20567e44e2cdea789bcd01f..ffdd35e7fba62831460cbcabbb765d4363caff28 100644
--- a/elements/standard/randomlossage.hh
+++ b/elements/standard/randomlossage.hh
@@ -28,7 +28,7 @@ class RandomLossage : public Element {
   RandomLossage(int p_drop = -1, bool = true);
   
   const char *class_name() const		{ return "RandomLossage"; }
-  void notify_outputs(int);
+  void notify_noutputs(int);
   void processing_vector(Vector<int> &, int, Vector<int> &, int) const;
   
   int p_drop() const				{ return _p_drop; }
diff --git a/elements/standard/tee.cc b/elements/standard/tee.cc
index 63f138dc2ee44fafb1a8b9b64599550696d674fe..af94f2cc98feb28ff113667c3518960913364fde 100644
--- a/elements/standard/tee.cc
+++ b/elements/standard/tee.cc
@@ -20,7 +20,7 @@
 Tee *
 Tee::clone() const
 {
-  return new Tee(noutputs());
+  return new Tee;
 }
 
 int
@@ -32,7 +32,7 @@ Tee::configure(const String &conf, ErrorHandler *errh)
 		  cpUnsigned, "number of arms", &n,
 		  0) < 0)
     return -1;
-  add_outputs(n - noutputs());
+  set_noutputs(n);
   return 0;
 }
 
@@ -78,7 +78,7 @@ PullTee::configure(const String &conf, ErrorHandler *errh)
     return -1;
   if (n == 0)
     return errh->error("number of arms must be > 0");
-  add_outputs(n - noutputs());
+  set_noutputs(n - noutputs());
   return 0;
 }
 
diff --git a/elements/standard/tee.hh b/elements/standard/tee.hh
index 95f87009abe98312d25d5809424e9697b1741933..e8a7c495a8f0c091254858a1046b460676956b63 100644
--- a/elements/standard/tee.hh
+++ b/elements/standard/tee.hh
@@ -24,7 +24,6 @@ class Tee : public Element {
  public:
   
   Tee()						: Element(1, 2) { }
-  explicit Tee(int n)				: Element(1, n) { }
   
   const char *class_name() const		{ return "Tee"; }
   Processing default_processing() const	{ return PUSH; }
diff --git a/lib/element.cc b/lib/element.cc
index 243ab37f945d507f171232806f278ada4bf3bea1..8e05ba623bfc44813a013224ae592204f382ba21 100644
--- a/lib/element.cc
+++ b/lib/element.cc
@@ -41,18 +41,8 @@ Element::Element(int ninputs, int noutputs)
   : ELEMENT_CTOR_STATS _refcount(0), _ninputs(0), _inputs(&_input0[0]),
     _noutputs(0), _outputs(&_output0[0])
 {
-  add_inputs(ninputs);
-  add_outputs(noutputs);
-  nelements_allocated++;
-}
-
-Element::Element(const Element &o)
-  : ElementLink(),
-    ELEMENT_CTOR_STATS _refcount(0), _ninputs(0), _inputs(&_input0[0]),
-    _noutputs(0), _outputs(&_output0[0])
-{
-  add_inputs(o._ninputs);
-  add_outputs(o._noutputs);
+  set_ninputs(ninputs);
+  set_noutputs(noutputs);
   nelements_allocated++;
 }
 
@@ -109,16 +99,14 @@ Element::context_message(const String &message) const
 // INPUTS AND OUTPUTS
 
 void
-Element::change_ports(int &store_n, Connection *&store_vec,
-		      Connection *store_inline, int count)
+Element::set_nports(int &store_n, Connection *&store_vec,
+		    Connection *store_inline, int new_n)
 {
-  if (count == 0 || store_n + count < 0)
-    return;
-  
+  if (new_n < 0) return;
   int old_n = store_n;
-  store_n += count;
+  store_n = new_n;
   
-  if (count < 0) {
+  if (new_n < old_n) {
     if (old_n > InlinePorts && store_n <= InlinePorts) {
       memcpy(store_inline, store_vec, store_n * sizeof(Connection));
       delete[] store_vec;
@@ -149,18 +137,18 @@ Element::change_ports(int &store_n, Connection *&store_vec,
 }
 
 void
-Element::add_inputs(int count)
+Element::set_ninputs(int count)
 {
-  change_ports(_ninputs, _inputs, &_input0[0], count);
+  set_nports(_ninputs, _inputs, &_input0[0], count);
 }
 
 void
-Element::notify_inputs(int)
+Element::notify_ninputs(int)
 {
 }
 
 int
-Element::set_input(int i, Element *f, int port)
+Element::connect_input(int i, Element *f, int port)
 {
   if (i >= 0 && i < ninputs() && _inputs[i].allowed()) {
     _inputs[i] = Connection(this, f, port);
@@ -170,18 +158,18 @@ Element::set_input(int i, Element *f, int port)
 }
 
 void
-Element::add_outputs(int count)
+Element::set_noutputs(int count)
 {
-  change_ports(_noutputs, _outputs, &_output0[0], count);
+  set_nports(_noutputs, _outputs, &_output0[0], count);
 }
 
 void
-Element::notify_outputs(int)
+Element::notify_noutputs(int)
 {
 }
 
 int
-Element::set_output(int o, Element *f, int port)
+Element::connect_output(int o, Element *f, int port)
 {
   if (o >= 0 && o < noutputs() && _outputs[o].allowed()) {
     _outputs[o] = Connection(this, f, port);
diff --git a/lib/element.hh b/lib/element.hh
index 3a26bdadd28f2dde141b11a1f4b9f7a3e6fbf0e0..965d8eabd1c6d1c428a7ec7230c7dbb2de3bbdb9 100644
--- a/lib/element.hh
+++ b/lib/element.hh
@@ -46,22 +46,22 @@ class Element : public ElementLink { public:
   int ninputs() const				{ return _ninputs; }
   const Connection &input(int input_id) const;
   
-  void add_input()				{ add_inputs(1); }
-  void add_inputs(int);
+  void add_input()				{ set_ninputs(ninputs()+1); }
+  void set_ninputs(int);
+  virtual void notify_ninputs(int);
   
-  virtual void notify_inputs(int);
-  int set_input(int input_id, Element *, int);
+  int connect_input(int input_id, Element *, int);
   
   // OUTPUTS
   int noutputs() const				{ return _noutputs; }
   const Connection &output(int output_id) const;
   void checked_push_output(int output_id, Packet *) const;
   
-  void add_output()				{ add_outputs(1); }
-  void add_outputs(int);
+  void add_output()				{ set_noutputs(noutputs()+1); }
+  void set_noutputs(int);
+  virtual void notify_noutputs(int);
   
-  virtual void notify_outputs(int);
-  int set_output(int output_id, Element *, int);
+  int connect_output(int output_id, Element *, int);
   
   // FLOW
   virtual Bitvector forward_flow(int) const;
@@ -167,7 +167,7 @@ class Element : public ElementLink { public:
   Element(const Element &);
   Element &operator=(const Element &);
   
-  void change_ports(int &, Connection *&, Connection *, int count);
+  void set_nports(int &, Connection *&, Connection *, int count);
   
 };
 
diff --git a/lib/router.cc b/lib/router.cc
index ed50c23e0cfdcd3bd54cd0184d50d925f7a0563a..ea8cf42b915c664e8a305b493144123b6c4db969 100644
--- a/lib/router.cc
+++ b/lib/router.cc
@@ -222,8 +222,8 @@ Router::notify_hookup_range()
       nin[_hookup_to[c].idx] = _hookup_to[c].port;
   }
   for (int f = 0; f < nelements(); f++) {
-    _elements[f]->notify_inputs(nin[f] + 1);
-    _elements[f]->notify_outputs(nout[f] + 1);
+    _elements[f]->notify_ninputs(nin[f] + 1);
+    _elements[f]->notify_noutputs(nout[f] + 1);
   }
 }
 
@@ -500,8 +500,8 @@ Router::set_connections()
     Element *fromf = _elements[hfrom.idx];
     Hookup &hto = _hookup_to[c];
     Element *tof = _elements[hto.idx];
-    fromf->set_output(hfrom.port, tof, hto.port);
-    tof->set_input(hto.port, fromf, hfrom.port);
+    fromf->connect_output(hfrom.port, tof, hto.port);
+    tof->connect_input(hto.port, fromf, hfrom.port);
   }
 }
 
diff --git a/lib/unlimelement.cc b/lib/unlimelement.cc
index 6a8cfc99f84ecd5dad035d402498018807848e05..0bac704005cba7034e62278c7053aea339156ec7 100644
--- a/lib/unlimelement.cc
+++ b/lib/unlimelement.cc
@@ -27,15 +27,15 @@ UnlimitedElement::UnlimitedElement(int ninputs, int noutputs)
 }
 
 void
-UnlimitedElement::notify_inputs(int n)
+UnlimitedElement::notify_ninputs(int n)
 {
   if (unlimited_inputs())
-    add_inputs(n - ninputs());
+    set_ninputs(n);
 }
 
 void
-UnlimitedElement::notify_outputs(int n)
+UnlimitedElement::notify_noutputs(int n)
 {
   if (unlimited_outputs())
-    add_outputs(n - noutputs());
+    set_noutputs(n);
 }
diff --git a/lib/unlimelement.hh b/lib/unlimelement.hh
index 8983bd8d47c3619f73467216cf2a171026298c5d..51fe5d3141dd9a4cd91cea2e595dd732a450668f 100644
--- a/lib/unlimelement.hh
+++ b/lib/unlimelement.hh
@@ -12,8 +12,8 @@ class UnlimitedElement : public Element {
   virtual bool unlimited_inputs() const		{ return false; }
   virtual bool unlimited_outputs() const	{ return false; }
   
-  void notify_inputs(int);
-  void notify_outputs(int);
+  void notify_ninputs(int);
+  void notify_noutputs(int);
 
 };