+ return @{$self->{nodes}};
+}
+
+sub parents
+{
+ my $self = shift;
+ return @{$self->{parent}};
+}
+
+sub rnodes
+{
+ my $self = shift;
+ my @out;
+ foreach my $call (@{$self->{nodes}}) {
+ next if grep $call eq $_, @_;
+ push @out, $call;
+ my $r = get($call);
+ push @out, $r->rnodes($call, @_) if $r;
+ }
+ return @out;
+}
+
+# return the differences in nodes between what we currently have and
+# the list proffered. Returns two refs one to a list of nodes to remove and
+# the other a list of nodes to add
+#
+# input is a list of callsigns (not refs)
+sub diff_nodes
+{
+ my $self = shift;
+ my $in = ref $_[0] ? shift : \@_;
+ my %del = map {($_, 1)} nodes($self);
+ my %in = map {($_, 1)} @$in;
+
+ # remove all the calls that are in both lists
+ for (@$in) {
+ delete $in{$_} if delete $del{$_};
+ }
+ return ([keys %del], [keys %in]);
+}
+
+# same as above but for users
+sub diff_users
+{
+ my $self = shift;
+ my $in = ref $_[0] ? shift : \@_;
+ my %del = map {($_, 1)} users($self);
+ my %in = map {($_, 1)} @$in;
+
+ # remove all the calls that are in both lists
+ for (@$in) {
+ delete $in{$_} if delete $del{$_};
+ }
+ return ([keys %del], [keys %in]);