diff --git a/apps/sam/perl/Net/SAM.pm b/apps/sam/perl/Net/SAM.pm
deleted file mode 100644
index 109330e1bbaf22953fdeb8451930e41e678e892a..0000000000000000000000000000000000000000
--- a/apps/sam/perl/Net/SAM.pm
+++ /dev/null
@@ -1,321 +0,0 @@
-#!/usr/bin/perl
-
-## Copyright 2004 Brian Ristuccia. This program is Free Software;
-## You can redistribute it and/or modify it under the same terms as
-## Perl itself. 
-
-package Net::SAM;
-
-@ISA = ( "IO::Socket::INET" ); 
-
-use strict;
-
-use POSIX;
-
-use Switch;
-
-use IO::Socket;
-use IO::Select;
-
-#use Net::SAM::StreamSession;
-#use Net::SAM::DatagramSession;
-#use Net::SAM::RawSession;
-
-sub new {
-    my ($class) = shift;
-    my $type = ref($class) || $class;
-    my $self = $type->SUPER::new("127.0.0.1:7656");
-
-
-    ${*$self}->{incomingraw} = [];
-
-    # Connect us to the local SAM proxy. 
-    # my $samsock = IO::Socket::INET->new('127.0.0.1:7657');
-    #$self->{samsock}=$samsock;
-
-    # Say hello, read response. 
-    $self->SUPER::send("HELLO VERSION MIN=1.0 MAX=1.0\n");
-    
-    while (! ${*$self}->{greeted}) { 
-	$self->readprocess();
-    }
-    print "Created SAM object\n";
-    return $self;
-}
-
-sub lookup {
-    my $self = shift;
-    my $name= shift;
-
-    $self->SUPER::send("NAMING LOOKUP NAME=$name\n");
-    undef ${*$self}->{RESULT};
-    while (! ${*$self}->{RESULT}) {
-	$self->readprocess();
-    }
-    if ( ${*$self}->{RESULT} == "OK" ) {
-	return ${*$self}->{VALUE};
-    } else {
-	return undef;
-    }
-}
-
-#sub createsession {
-#    my ($self) = shift;
-#    my ($sesstype) = shift;
-#    print $self->{samsock} "SESSION CREATE STYLE=$SESSTYPE DESTINATION=$DEST, DIRECTION=
-#}
-
-#sub waitfor {
-#    my ($self) = shift;
-#    my ($prefix) = shift;
-#    my ($response) = <$samsock>;#
-
- #   if $response =~ 
-    
-
-#}
-
-
-sub readprocesswrite {
-    my $self = shift;
-    $self->readprocess();
-    $self->dowrite();
-}
-
-sub doread {
-    my $self = shift;
-    my $rv;
-    my $data;
-    
-    $rv = $self->recv($data, $POSIX::BUFSIZE, 0);
-
-    if ( defined($rv) && ( length($data) >= 1 ) ) {
-	# We received some data. Put it in our buffer.
-	${*$self}->{inbuffer} += $data;
-    } else {
-	# No data. Either we're on a non-blocking socket, or there 
-	# was an error or EOF
-	if ( $!{EAGAIN} ) {
-	    return 1;
-	} else {
-	    # I suppose caller can look at $! for details
-	    return undef; 
-	}
-    }
-}
-
-
-sub dowrite {
-    my $self = shift;
-    my $rv;
-    my $data; 
-
-    $rv = $self->send(${*$self}->{outbuffer}, 0);
-    
-    if ( ! defined($rv) ) {
-	warn "SAM::dowrite - Couldn't write for no apparent reason.\n";
-	return undef; 
-    }
-
-    if ( $rv == length(${*$self}->{outbuffer}) || $!{EWOULDBLOCK} ) {
-	substr(${*$self}->{outbuffer},0, $rv) = ''; # Remove from buffer
-
-	# Nuke buffer if empty
-	delete ${*$self}->{outbuffer} unless length(${*$self}->{outbuffer});
-    } else {
-	# Socket closed on us or something?
-	return undef;
-    }
-}
-
-sub messages {
-    my $self = shift;
-    
-    return @{ ${*$self}->{messages} };
-}
-
-sub queuemessage {
-
-    my $self = shift;
-    my $message = shift; 
-    
-    push @{ ${*$self}->{messages} } , $message;
-}
-
-sub unqueuemessage {
-    my $self = shift;
-    
-    return unshift(@{ ${*$self}->{messages} } );
-    
-}
-
-sub readprocess {
-    my $self = shift;
-
-    $self->doread();
-    $self->process();
-}
-
-sub process {    
-    my $self = shift;
-    my %tvhash; 
-    my $payload; 
-    
-
-    # Before we can read any new messages, if an existing message has payload
-    # we must read it in. Otherwise we'll create garbage messages containing
-    # the payload of previous messages. 
-
-    if ( ${*$self}->{payloadrequired} >= 1 ) {
-
-	if ( length( ${*$self}->{inbuffer} ) >= ${*$self}->{payloadrequired} ) {
-	    # Scarf payload from inbuffer into $payload
-	    $payload = substr(${*$self}->{inbuffer}, 0, 
-			      ${*$self}->{payloadrequired});
-	    
-	    # Nuke payload from inbuffer
-	    substr(${*$self}->{inbuffer}, 0,
-		   ${*$self}->{payloadrequired} ) = '';
-	    
-	    # Put message with payload into spool
-	    push @{ ${*$self}->{messages} } , 
-	    ${*$self}->{messagerequiringpayload}.$payload;
-
-	    # Delete the saved message requiring payload
-	    delete ${*$self}->{messagerequiringpayload};
-	} else {
-	    # Insufficient payload in inbuffer. Try again later. 
-	    return 1;
-	}
-
-    }
-
-
-    if ( ${*$self}->{inbuffer} =~ s/(.*\n)// ) {
-	%tvhash = $self->_hashtv($1); # Returns a tag/value hash
-	if ( $tvhash{SIZE} ) {
-	    # We've got a message with payload on our hands. :(
-	    ${*$self}->{payloadrequired} = $tvhash{SIZE}; 
-	    ${*$self}->{messagerequiringpayload} = $1; 
-	    return 1; # Could call ourself here, but we'll get called again. 
-	} else {
-	    push @{ ${*$self}->{messages} } , $1;
-	}
-    }
-    return 1; 
-}
-
-# sub junk {
-
-
-#     print "readprocess: " . $self->connected() . "\n";
-
-#     # May block if the SAM bridge gets hosed
-#     my $response = <$self>;
-
-#     print "readprocess: $!" . $self->connected() . "\n";
-
-#     chomp $response;
-#     my ($primative, $more, $extra) = split (' ', $response, 3);
-
-#     $primative = uc($primative);
-
-#     print "readprocess: " . $self->connected() . " -- $primative -- $more -- $extra\n";
-
-#     switch ($primative) {
-
-# 	case "HELLO" {
-# 	    if ($more !~ m/REPLY/ ) { die ("Bogus HELLO response") }
-# 	    if ($extra =~ m/NOVERSION/ ) { 
-# 		die("SAM Bridge Doesn't support my version") ;
-# 	    }
-# 	    $self->_hashtv($extra);
-# 	    ${*$self}->{greeted} = 1;
-# 	};
-# 	case "SESSION" {
-# 	    if ( $more !~ m/STATUS/ ) {
-# 		die("Bogus SESSION response");
-# 	    }
-# 	    $self->_hashtv($extra);
-# 	}
-# 	case "STREAM" {};
-# 	case "DATAGRAM" {
-# 	    if ( $more !~ m/RECEIVE/ ) {
-# 		die("Bogus DATAGRAM response.");
-# 	    }
-# 	    $self->_hashtv($extra);
-# 	    push @{ ${*$self}->{incomingdatagram } }, 
-# 		    [ ${*$self}->{DESTINATION},
-# 		      $self->_readblock(${*$self}->{SIZE}) ];
-		      
-# 	};
-# 	case "RAW" {
-# 	    if ( $more !~ m/RECEIVE/ ) {
-# 		die("Bogus RAW response.");
-# 	    }
-# 	    $self->_hashtv($extra);
-
-# 	    push @{ $self->{incomingraw} }, $self->_readblock($self->{SIZE});
-# 	};
-# 	case "NAMING" {
-# 	    if ( $more !~ m/REPLY/ ) {
-# 		die("Bogus NAMING response");
-# 	    }
-# 	    $self->_hashtv($extra);
-# 	};
-# 	case "DEST" {};
-#     }
-#     return 1; 
-# }
-
-sub getfh {
-    # Return the FH of the SAM socket so apps can select() or poll() on it
-    my $self = shift;
-    return $self->{samsock};
-}
-
-sub _readblock {
-    my $self = shift;
-    my $size = shift; 
-    my $chunk;
-    my $payload;
-
-    while ( $size > 1 )  {
-	# XXX: May block. No error checking. 
-	print "readblock: $size\n";
-	$size -= $self->SUPER::recv($chunk, $size);
-	$payload .= $chunk;
-    }
-    return $payload; 
-}
-
-sub _hashtv {
-    my $self = shift;
-    my $tvstring = shift;
-    my $tvhash;
-
-    while ( $tvstring =~ m/(\S+)=(\S+)/sg ) {
-	$tvhash->{$1}=$2;
-	print "hashtv: $1=$2\n"
-    }
-    return $tvhash;
-}
-
-sub DESTROY {
-    # Do nothing yet. 
-}
-
-#sub StreamSession {
-#    my $self = shift;
-#    return Net::SAM::StreamSession->new($self);
-#}
-
-#sub DatagramSession {
-#    return Net::SAM::DatagramSession->new($self);
-#}
-
-#sub RawSession {
-#    return Net::SAM::RawSession->new($self);
-#}
-
-1;
diff --git a/apps/sam/perl/Net/SAM/DatagramSession.pm b/apps/sam/perl/Net/SAM/DatagramSession.pm
deleted file mode 100644
index ba583d0fc4335c6539d6e2a1c8600b8bac890a57..0000000000000000000000000000000000000000
--- a/apps/sam/perl/Net/SAM/DatagramSession.pm
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/perl
-
-package Net::SAM::DatagramSession;
-
-use Net::SAM;
-
-@ISA = ("Net::SAM");
-
-sub new {
-    my ($class) = shift;
-    my ($dest , $direction, $options) = shift; 
-
-    my $self = $class->SUPER::new(@_);
-
-    $self->SUPER::send("SESSION CREATE STYLE=DATAGRAM DESTINATION=$dest DIRECTION=$direction $options\n");
-
-    undef ${*$self}->{RESULT};
-
-    while ( ! ${*$self}->{RESULT} ) {
-	$self->readprocess() || return undef;
-	   
-    }
-
-    if ( ${*$self}->{RESULT} == "OK" ) {
-	return $self;
-    } else {
-	return undef; # sorry.
-    }
-}
-
-sub send {
-    my $self = shift;
-    my $destination = shift;
-    my $message = shift;
-    my $size = length($message);
-    $self->SUPER::send("DATAGRAM SEND DESTINATION=$destination SIZE=$size\n$message");
-}
-
-sub receive {
-    my $self = shift;
-
-    # Shift one off the fifo array. Returns undef if none wait. 
-    return shift @{ $self->{incomingdatagram} };
-}
-
-
-
-1;
diff --git a/apps/sam/perl/Net/SAM/RawSession.pm b/apps/sam/perl/Net/SAM/RawSession.pm
deleted file mode 100644
index 971d405df065de2b6d1f6aa83e3f1483004fecb5..0000000000000000000000000000000000000000
--- a/apps/sam/perl/Net/SAM/RawSession.pm
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/perl
-
-package Net::SAM::RawSession;
-
-use Net::SAM;
-
-@ISA = ("Net::SAM");
-
-sub new {
-    my ($class) = shift;
-    my ($dest , $direction, $options) = shift; 
-
-    my $self = $class->SUPER::new(@_);
-
-    $self->send("SESSION CREATE STYLE=RAW DESTINATION=$dest DIRECTION=$direction $options\n");
-
-    undef $self->{result};
-    while ( ! $self->{RESULT} ) {
-	$self->readprocess();
-    }
-
-    if ( $self->{RESULT} == "OK" ) {
-	return $self;
-    } else {
-	return 0; # sorry.
-    }
-}
-
-sub send {
-    my $self = shift;
-    my $destination = shift;
-    my $message = shift;
-    my $samsock = $self->{samsock};
-    my $size = length($message);
-    print $samsock "RAW SEND DESTINATION=$destination SIZE=$size\n$message";
-}
-
-sub receive {
-    my $self = shift;
-
-    # Shift one off the fifo array. Returns undef if none wait. 
-    return shift @{ $self->{incomingraw} };
-}
-
-1;
diff --git a/apps/sam/perl/Net/SAM/StreamSession.pm b/apps/sam/perl/Net/SAM/StreamSession.pm
deleted file mode 100644
index 562ec880de93f06db0df28dd7cccba1c31862b5c..0000000000000000000000000000000000000000
--- a/apps/sam/perl/Net/SAM/StreamSession.pm
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/perl
-
-1;
diff --git a/apps/sam/perl/README b/apps/sam/perl/README
new file mode 100644
index 0000000000000000000000000000000000000000..865377e625f2b9b6e1daabeeabd0e0c405f74c6f
--- /dev/null
+++ b/apps/sam/perl/README
@@ -0,0 +1,108 @@
+# BASIC Perl SAM Module
+# created 2005 by postman (postman@i2pmail.org)
+
+
+1. What does it do?
+
+The SAM module is a little Perl add-on that  - on one side -
+establishes communication with a I2P router's (http://www.i2p.net) SAM bridge
+(Simple anonymous messaging ( http://www.i2p.net/sam)). On the
+other side it exposes a simple socket like interface to the user.
+Over this interface the user can send or receive datastreams from I2P 
+destinations as if he would communicate with a normal IP socket.
+
+The SAM module can be integrated into perl scripts that
+want to communicate with I2P services.
+
+
+2. Is this code usable?
+
+This perl module should be considered as proof-of-concept
+quality. It did surely work for me and my test setups, but
+it might not work at all on your system. If you run into problems
+you can contact me.
+
+
+3. Does ist support DATAGRAM and RAW sessions?
+
+No, at the moment the module only supports STREAM sessions.
+Support for other session types might be added in the future.
+
+
+4. How to install it?
+Create a Subfolder called I2P  in your Perl Installation's Net Module 
+folder (i.e. /usr/lib/perl5/5.8.4./Net/I2P ) and copy the module there.
+You can now use it with use Net::I2P::SAM. 
+The module only depends on Net::IO::Socket for operations. This
+should be already installed.
+
+
+5. How to debug?
+You can switch on debugging with the constructor ( see below ).
+
+
+6. How to use it?
+
+
+$sam = new Net::I2P::SAM('127.0.0.1','7656',1);
+
+# you can omit host/port - then the defult is assumed
+# the 3rd argument is the debugging switch. If you switched it on
+# there'll be a default debug in /tmp/sam-debug
+# $sam will now either contain a object reference or 0
+# if it's 0 then we coudl not talk to the SAM bridge at all ( connect failed)
+# or we could not agree to a version
+
+# next we can tune the tunnel settings we want for this session:
+# The syntax is just like the one used on www.i2p.net/sam
+
+$sam->change_settings("inbound.length=1,inbound.lenghVariance=0,outbound.length=1,outbound.lengthVariance=0,inbound.nickname=fun,outbound.nickname=fun");
+
+# next we open a new session. 
+# only stream is supported
+# most of the time we use a transient destination
+# otherwise state the hosts.txt name you want to use as in your session
+# direction is most of the times both :)
+# this cab return 1 for success or 0 for failure
+$sam->create_session("STREAM","TRANSIENT","BOTH");
+
+
+# now connect to our service
+$sam->connect($sam->lookup("myservice.i2p"));
+
+# or 
+
+$sam->connect("I2PDESTINATIONKEY.....AAAA");
+
+# if this returns 1 - we got a stream session and can now receive and send data
+# otherwise consult the debug.
+
+
+
+# Send data is just like the the raw perl send
+# we send the data as scalar var and optional flags (most of the times 0)
+$sam->send($data,0);
+
+
+# receiving data is similar to the perl recv
+# we define the mac number of bytes and optional flags
+
+$indata = $sam->receive(512,0);
+
+# close the session
+
+$sam->close();
+
+# that's the most important things to know.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/sam/perl/SAM.pm b/apps/sam/perl/SAM.pm
new file mode 100644
index 0000000000000000000000000000000000000000..54ffdc0485593b22cbd8ba05b46a9afc82ea50a3
--- /dev/null
+++ b/apps/sam/perl/SAM.pm
@@ -0,0 +1,922 @@
+# Perl Basic SAM module
+# created 2005 by postman (postman@i2pmail.org)
+# This code is under GPL.
+# This code is proof of concept
+
+
+package Net::I2P::SAM;
+require 5.001;
+use strict;
+use POSIX;
+
+
+# we do not extend the IO::Socket:INET Package
+# we just use it, so we keep our stuff sorted  
+# This is a testsetup - the next release but
+# be an extension of IO::Socket::INET;
+
+use IO::Socket::INET;
+
+
+use vars qw($VERSION @ISA @EXPORT);
+
+
+sub new {
+  my ($this,$host,$port,$debug) = @_;
+  my $classname=ref($this) || $this;
+  my $self = {};
+  bless($self,$classname);
+  
+
+  #%{$self->{conf}}     = The hash where we store tunnel / SAM Settings
+  #$self->{debug}       = Whether we should output debugging lines ( this is very helpful when having problems)
+  #$self->{debugfile}   = Where to log
+  #%{$self->{samreply}} = This hash stores the key=VALUE pairs of sam reply 
+  #$self->{sock}        = The INET Socket over which we talk to the SAM bridge
+  #$self->{inbuffer}    = a simple layouted inbuffer 
+  #$self->{outbuffer}   = a simple layouted outbuffer 
+  #                      ( the buffers are for dealing with differences between user wanted in/outputsizes
+  #                        and what we're able to deliver on a machine side)
+  #$self->{sessiontype} = unused ( will be used when we support different sessiontypes )
+  #$self->{lookupresult}= contains the result of a SAM host/userhost naming lookup;
+  #$self->{samerror}    = The human readable SAM error message ( if wanted )
+  #$self->{streamid}    = The virtual streamid. It will be created upon connect;
+  #$self->{bytestoread} = contains the reported size of a packet from sam
+  #$self->{bytestosend} = contains the wanted size of a packet to sam
+  #$self->{hasbanner}   = is set to 1 when we receive a greeting string upon connect
+  
+  #
+
+  %{$self->{conf}}=();
+  if($debug==1) {
+  	$self->{debug}=1;
+  }
+  $self->{debugfile}="/tmp/sam-debug";
+  $self->{debughandle}=undef;
+  %{$self->{samreply}}=undef; 
+  $self->{sock}=undef;
+  $self->{inbuffer}=undef;
+  $self->{outbuffer}=undef;
+  $self->{sessiontype}=undef;
+  $self->{lookupresult}=undef;
+  $self->{samerror}=undef;
+  $self->{streamid}=undef;
+  $self->{bytestoread}=undef;
+  $self->{bytestosend}=undef;
+  $self->{hasbanner}=1;
+
+  # state == -1 (no socket exists)
+  # state == 0  (socket exists, but we're not helloed)
+  # state == 1  (socket exists, and we're helloed)
+  # state == 200 ( we bound a session)
+  # state == 250 ( we have a virtual stream)
+  
+  $self->{state}=-1;
+
+  
+  # if the user has specified a host/port for contacting the SAM
+  # Bridge, we'll override the defaults. Otherwise we just use 
+  # defaults.
+  # 
+  if($host) {
+    ${$self->{conf}}{host}=$host;
+  } else { 
+    ${$self->{conf}}{host}="127.0.0.1";
+  }
+
+  if($port) {
+    ${$self->{conf}}{port}=$port;
+  } else {
+    ${$self->{conf}}{port}=7656;
+  }
+  # defaults for the tunnelparameters
+  # see www.i2p.net/sam
+  ${$self->{conf}}{iblength}=2;
+  ${$self->{conf}}{oblength}=2;
+  ${$self->{conf}}{ibquant}=2;
+  ${$self->{conf}}{obquant}=2;
+  ${$self->{conf}}{ibbackup}=0;
+  ${$self->{conf}}{obbackup}=0;
+  ${$self->{conf}}{ibvariance}=0;
+  ${$self->{conf}}{obvariance}=0;
+  ${$self->{conf}}{iballowzero}="true";
+  ${$self->{conf}}{oballowzero}="true";
+  ${$self->{conf}}{ibduration}=600000;
+  ${$self->{conf}}{obduration}=600000;
+  ${$self->{conf}}{ibnickname}="SAM-Perl-Destination";
+  ${$self->{conf}}{obnickname}="SAM-Perl-Destination";
+  
+  
+
+  # ok, let's open a simple debug file
+  # if the user wants us
+  if($self->{debug} == 1) {
+    if ( ! open (LOGFILE,">" .$self->{debugfile})) {
+      print "constructor: Cannot open debugging file, switching debugging off.";
+      $self->{debug}=0;
+    }
+    
+    # switch off the nerveracking buffer for the debugfile
+    select((select(LOGFILE), $| = 1)[0]);
+  }
+  
+  # ok now, lets move to the manager
+  # he manages connecting and hello
+  # if the proc_mgr returns 1 the user will get our
+  # object reference. if not, he'll just get a 0.
+  if($self->proc_mgr()) {
+    return $self;
+  } else {
+    return 0;
+  }
+  
+}
+
+sub proc_mgr {
+  my ($self) = @_;
+  my $return=undef;
+  
+  if ($self->{state} == -1) {
+    $self->log("Debug: SAM::proc_mgr(): Opening Socket Connection to ".${$self->{conf}}{host}.":".${$self->{conf}}{port});   
+    $return=$self->sam_connect();
+    if($return==0) {
+      return 0;
+    }
+    if($return == 1) {
+      $self->log("Debug: SAM::proc_mgr(): State Transition -1 => 0");
+      $self->{state}=0;
+    }
+  }
+  
+  
+  if($self->{state}==0) {
+     if(!$self->hello()) {
+       $self->log("Debug: SAM::proc_mgr(): Closing Socket");
+       $self->{sock}->close();
+       $self->log("State SAM::proc_mgr(): Transition 0 => -1");
+       return 0;
+     }
+  }
+
+  return 1; 
+
+}
+
+
+sub change_settings {
+  my ($self,$list)=@_;
+  my (@tochange,$id,$v,$k);
+  
+  # we cannot change the settings if we have a session already
+  # so our state must be 1
+
+  if($self->{state} >1) {
+    $self->log("Debug: SAM::change_settings(): Cannot change tunnel settings after establishing a session.");
+    return 0;
+  }
+  
+  @tochange=split(",",$list);
+  foreach $id (@tochange) {
+    ($k,$v)=split("=",$id);
+    lc($v);
+    lc($k);
+    
+
+    $self->log("Debug: SAM::change_settings(): Parsed Setting: Key: $k - Value: $v");
+    if($k eq "inbound.length" || $k eq "outbound.length") {
+      # make v an int
+      $v*1;
+      if ($v >3 || $v < 0) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (out of range)");
+	return 0;
+      }
+      
+      if(${$self->{conf}}{iballowzero} eq "false" && $k eq "inbound.length" && $v==0) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (length forbidden by allowzero=false)");
+	return 0;
+      }
+      
+      if(${$self->{conf}}{oballowzero} eq "false" && $k eq "outbound.length" && $v==0) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (length forbidden by allowzero=false)");
+	return 0;
+      }
+      
+      if($k eq "inbound.length") {
+        ${$self->{conf}}{iblength}=$v;
+      }
+      if($k eq "outbound.length") {
+        ${$self->{conf}}{oblength}=$v;
+      }
+
+
+      
+    }
+    
+    if($k eq "inbound.quantity" || $k eq "outbound.quantity") {
+      $v*1;
+      if($v < 0 || $v >3 ) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (out of range)");
+	return 0;
+      }
+
+      if ($k eq "inbound.quantity") {
+        ${$self->{conf}}{ibquant}=$v;
+      }
+      if($k eq "outbound.quantity") {
+        ${$self->{conf}}{obquant}=$v;
+      }
+    }
+
+    if($k eq "inbound.backupquantity" || $k eq "outbound.backupquantity") {
+      $v*1;
+      if($v < 0 || $v >2 ) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (out of range)");
+	return 0;
+      }
+
+      if ($k eq "inbound.backupquantity") {
+        ${$self->{conf}}{ibbackup}=$v;
+      }
+      if($k eq "outbound.backupquantity") {
+        ${$self->{conf}}{obbackup}=$v;
+      }
+    }
+
+    if($k eq "inbound.lengthvariance" || $k eq "outbound.lengthvariance") {
+      $v*1;
+      if($v < -2  || $v >2 ) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (out of range)");
+	return 0;
+      }
+
+      if ($k eq "inbound.lengthvariance") {
+        ${$self->{conf}}{ibvariance}=$v;
+      }
+      if($k eq "outbound.lengthvariance") {
+        ${$self->{conf}}{ibvariance}=$v;
+      }
+    }
+    
+    if($k eq "inbound.duration" || $k eq "outbound.duration") {
+      $v*1;
+      if($v < 300000  || $v >1200000 ) {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (out of range)");
+	return 0;
+      }
+
+      if ($k eq "inbound.duration") {
+        ${$self->{conf}}{ibduration}=$v;
+      }
+      if($k eq "outbound.duration") {
+        ${$self->{conf}}{obduration}=$v;
+      }
+    }
+    
+    if($k eq "inbound.nickname" || $k eq "outbound.nickname") {
+      $v=substr($v,0,20);
+
+      if ($k eq "inbound.nickname") {
+        ${$self->{conf}}{ibnickname}=$v;
+      }
+      if($k eq "outbound.nickname") {
+        ${$self->{conf}}{obnickname}=$v;
+      }
+    }
+     
+    if($k eq "inbound.allowzerohop" || $k eq "outbound.allowzerohop") {
+      if($v ne "true" && $v ne "false") {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (must be boolean)");
+	return 0;
+      }
+      
+      if(${$self->{conf}}{iblength} ==0  && $k eq "inbound.allowzerohop" && $v eq "false") {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (length forbidden by allowzero=false)");
+	return 0;
+      }
+      
+      if(${$self->{conf}}{oblength} == 0  && $k eq "outbound.allowzerohop" && $v eq "false") {
+        $self->log("Error: SAM::change_settings(): Wrong value $v is not valid for $k (length forbidden by allowzero=false)");
+	return 0;
+      }
+
+      
+      if ($k eq "inbound.allowzerohop") {
+        ${$self->{conf}}{iballowzero}=$v;
+      }
+      if($k eq "outbound.allowzerohop") {
+        ${$self->{conf}}{oballowzero}=$v;
+      }
+    }
+     
+    $self->log("Debug: SAM::change_settings(): Setting $k to $v");
+
+    
+  }
+  
+  return 1;
+
+}
+
+
+sub hello {
+  my ($self) = @_;
+  my $greeting="HELLO VERSION MIN=1.0 MAX=1.0\n";
+  my $return=undef;
+  my $return2=undef;
+  
+  $self->{outbuffer} .= $greeting;
+  $return=$self->raw_send();
+  if($return == 1) {
+    if($self->raw_read()) {
+      if($self->parse_sam("HELLO")) {
+	$self->{state}=1;
+	$self->log("Debug: SAM::hello(): State Transition 0 => 1");
+	delete $self->{inbuffer};
+	delete $self->{outbuffer};
+	return 1;
+      }
+    } else {
+      $self->log("Error: SAM::hello():  HELLO Failed. Cannot read HELLO response");
+      return 0;
+    }
+  }
+
+  if($return == 0) {
+    $self->log("Error: SAM::hello():  HELLO Failed. Cannot send HELLO String");
+    return 0;
+  }
+
+}
+
+
+sub create_session {
+  my ($self,$type,$destination,$direction) = @_;  
+  my $line="SESSION CREATE ";
+  my $return;
+  
+  uc($type);
+  # WE ARE ONLY DOING STREAMS ATM
+  if ($type ne "STREAM") {
+    $self->log("Error: SAM::create_session(): SESSION failed. Only session of STREAM type are allowed");
+    return 0;
+  }
+  if(length($destination)==0) {
+    $self->log("Warn: SAM::create_session(): SESSION: fallback setting on destination to TRANSIENT.");
+    $destination="TRANSIENT";
+  }
+  
+  $line.="STYLE=$type DESTINATION=$destination";
+  
+  uc($direction);
+  if($direction ne "BOTH" && $direction ne "CREATE" && $direction ne "RECEIVE") {
+    $self->log("Warn: SAM::create_session(): SESSION: fallback setting on direction to BOTH.");
+    $direction="BOTH";
+  }
+  
+  $line .= " DIRECTION=$direction";
+  $line .= " inbound.length=".${$self->{conf}}{iblength}." outbound.length=".${$self->{conf}}{oblength};
+  $line .= " inbound.quantity=".${$self->{conf}}{ibquant}." outbound.quantity=".${$self->{conf}}{obquant};
+  $line .= " inbound.backupQuantity=".${$self->{conf}}{ibbackup}." outbound.backupQuantity=".${$self->{conf}}{obbackup};
+  $line .= " inbound.lengthVariance=".${$self->{conf}}{ibvariance}." outbound.lengthVariance=".${$self->{conf}}{obvariance};
+  $line .= " inbound.duration=".${$self->{conf}}{ibduration}." outbound.duration=".${$self->{conf}}{obduration};
+  $line .= " inbound.nickname=".${$self->{conf}}{ibnickname}." outbound.nickname=".${$self->{conf}}{obnickname};
+  $line .= " inbound.allowZeroHop=".${$self->{conf}}{iballowzero}." outbound.allowZeroHop=".${$self->{conf}}{oballowzero};
+  $line .="\n";
+
+  $self->{outbuffer}.=$line;
+  $return=$self->raw_send();
+ 
+  if($return == 1) {
+    if($self->raw_read()) {
+      if($self->parse_sam("SESSION ")) {
+	$self->{state}=200;
+	$self->log("Debug: SAM::create_session(): State Transition 1 => 200");
+	# flush the whole inbuffer;
+	delete $self->{inbuffer};
+	delete $self->{outbuffer};
+	return 1;
+      }
+    } else {
+      $self->log("Error: SAM::create_session(): SESSION Failed. Cannot read SAM Response");
+      return 0;
+    }
+  }
+
+  if($return == 0) {
+    $self->log("Error: SAM::create_session(): SESSION Failed. Cannot send SESSION String");
+    return 0;
+  }
+
+ 
+
+}
+
+
+
+
+sub parse_sam {
+
+  # this is the main function that parses all SAM replies
+  # depending on wanted action and state we'll set different
+  # properties like $self->{bytestoread} etc.
+  # parse_sam does not CUT OUT SAM messages from the payloads 
+  # (look at $self->recv for that)
+  #
+  my ($self,$state) = @_;
+  my (@data,$id,$k,$v);
+  %{$self->{samreply}}=();
+  
+  
+  uc($state);
+  
+  if( $self->{inbuffer} =~ /^(.[^ ]*) (.[^ ]*) (.*)$/m ) {
+    ${$self->{samreply}}{COMMAND}=$1;
+    ${$self->{samreply}}{REPLY}=$2;
+    
+    @data=split(" ",$3);
+    
+    foreach $id (@data) {
+      ($k,$v)=split("=",$id);
+
+      #print "k: $k - v: $v\n";
+      ${$self->{samreply}}{$k}=$v;
+    }
+  } else {
+    $self->log("Error: SAM::parse_sam(): Could not parse the SAM Reply. Has the specs changed?");
+    return 0;
+  }
+ 
+  if($state eq "HELLO") {
+    if (${$self->{samreply}}{COMMAND} ne "HELLO") {
+      $self->log("Error: SAM::parse_sam(): We're in state HELLO but got no proper response from SAM");
+      return 0;
+    }
+    
+    if(${$self->{samreply}}{REPLY} eq "REPLY") {
+      if(${$self->{samreply}}{RESULT}  eq "OK") {
+        $self->log("Debug: SAM::parse_sam(): Got a OK result for HELLO");
+	return 1;
+      } else {
+        $self->log("Error :SAM::parse_sam(): Got no OK Result for HELLO");
+	return 0;
+      }
+    } else {
+      $self->log("Error: SAM::parse_sam(): Unknown Reply type for HELLO dialogue");
+      return 0;
+    }
+  }
+
+  if($state eq "SESSION") {
+    if (${$self->{samreply}}{COMMAND} ne "SESSION") {
+      $self->log("Error: SAM::parse_sam(): We're in state SESSION but got no proper response from SAM");
+      return 0;
+    }
+    
+    if(${$self->{samreply}}{REPLY} eq "STATUS") {
+      if(${$self->{samreply}}{RESULT} eq "OK") {
+        $self->log("Debug: SAM::parse_sam(): Got a OK result for SESSION");
+	return 1;
+      } else {
+        $self->log("Error: SAM::parse_sam(): Got no OK Result for SESSION: ".${$self->{samreply}}{RESULT});
+	return 0;
+      }
+    } else {
+      $self->log("Error: SAM::parse_sam(): Unknown Reply type for SESSION dialogue");
+      return 0;
+    }
+  }
+
+  if($state eq "NAMING") {
+    if (${$self->{samreply}}{COMMAND} ne "NAMING") {
+      $self->log("Error: SAM::parse_sam(): We're in state NAMING but got no proper response from SAM");
+      return 0;
+    }
+    
+    if(${$self->{samreply}}{REPLY} eq  "REPLY") {
+      if(${$self->{samreply}}{RESULT} eq "OK") {
+        $self->log("Debug: SAM::parse_sam(): Got a OK result for NAMING");
+	$self->{lookupresult}=${$self->{samreply}}{VALUE};
+	return 1;
+      } else {
+        $self->log("Error: SAM::parse_sam(): Got no OK Result for NAMING: ".${$self->{samreply}}{RESULT});
+	return 0;
+      }
+    } else {
+      $self->log("Error: SAM::parse_sam(): Unknown Reply type for NAMING dialogue");
+      return 0;
+    }
+  }
+
+  if($state eq "STREAM") {
+    if (${$self->{samreply}}{COMMAND} ne "STREAM") {
+      $self->log("Error: SAM::parse_sam(): We're in state STREAM but got no proper response from SAM");
+      return 0;
+    }
+    
+    # CREATING STREAMS
+    if(${$self->{samreply}}{REPLY} eq "STATUS") {
+      if(${$self->{samreply}}{RESULT} eq "OK") {
+        $self->log("Debug: SAM::parse_sam(): STREAM STATUS OK - Next action is awaited");
+	return 1;
+      } else {
+        $self->log("Error: SAM::parse_sam(): STREAM STATUS NOT OK.: ".${$self->{samreply}}{RESULT});
+	
+	if(length(${$self->{samreply}}{MESSAGE}) == 0) { 
+	  $self->{samerror}=${$self->{samreply}}{RESULT};
+	} else {
+	  $self->{samerror}=${$self->{samreply}}{MESSAGE};
+	}
+	return 0;
+      }
+    } 
+    
+    # SEND/RECEIVING STREAMS
+    # this can happen directly after a connect 
+    if(${$self->{samreply}}{REPLY} eq "RECEIVED") {
+      if(${$self->{samreply}}{SIZE} > 0) {
+        $self->log("Debug: SAM::parse_sam(): SAM notify: RECEIVED Data. SIZE=".${$self->{samreply}}{SIZE});
+	$self->{bytestoread}=${$self->{samreply}}{SIZE};
+	return 1;
+      } else {
+        $self->log("Error: SAM::parse_sam(): Received empty payload");
+	return 0;
+      }
+    }
+    
+    # STREAMS are closed - bad thing
+    # this can happen directly after a connect 
+    if(${$self->{samreply}}{REPLY} eq "CLOSED") {
+      $self->log("Error: SAM::parse_sam(): Stream is closed: We need to interupt the session");
+      return 0;
+    }
+
+
+    
+  }
+
+
+}
+
+
+sub raw_send {
+
+  # this function sends a crafted SAM request + payload to the
+  # SAM socket
+  my ($self) = @_;
+  my $return;
+  
+  $self->log("Debug: SAM::raw_send(): >>> ".$self->{outbuffer});
+  $return = $self->{sock}->send($self->{outbuffer},0);
+  if(! defined($return)) {
+    $self->log("Error: SAM::raw_send(): Cannot send to Socket");
+    $self->close();
+    return 0;
+  }
+  
+  if ( $return == length($self->{outbuffer}) || $!{EWOULDBLOCK} ) {
+    substr($self->{outbuffer},0, $return) = '';
+    delete $self->{outbuffer} unless length($self->{outbuffer});
+    return 1;
+  } else {
+    $self->log("Error :SAM::raw_send(): Could send, but length does not match. Closing");
+    $self->close();
+    return 0;
+  }
+}
+
+sub raw_read {
+  my ($self,$size) = @_;
+  my $input;
+  my $data;
+
+  # this reads SAM replies from the SAM socket and fills the
+  # inbuffer
+
+  if(!$size || $size > POSIX::BUFSIZ) {
+    $size=POSIX::BUFSIZ;
+  }
+
+  
+  $input = $self->{sock}->recv($data, $size, 0);
+  
+  if(defined($input) && length($data) >= 1) {
+
+  
+    $self->log("Debug: SAM::raw_read(): <<< $data");
+    if(length($self->{inbuffer}) == 0 ) {
+      $self->{inbuffer} = $data;
+    } else {
+      $self->{inbuffer} .= $data;
+    }
+    
+    return 1;    
+  
+  } else {
+    if ( $!{EAGAIN} ) {
+      $self->{bytestoread}=0;
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+  
+
+  
+}
+
+sub sam_connect {
+  # bsic connect to the sam bridge socket itself
+  my ($self)=@_;
+  my $return=undef;
+ 
+
+ 
+  $return=$self->{sock}=IO::Socket::INET->new(${$self->{conf}}{host}.":".${$self->{conf}}{port}); 
+  
+  if($return==0) {
+    $self->log("Debug: SAM::sam_connect(): Connection failed to ".${$self->{conf}}{host}.":".${$self->{conf}}{port}); 
+    return 0;
+  } else {
+    $self->log("Debug: SAM::sam_connect(): Connection established to ".${$self->{conf}}{host}.":".${$self->{conf}}{port}); 
+    return 1;
+  }
+}
+
+sub send {
+
+  # the public fumction to send data to sam
+  # the user gives his payload and we create
+  # valid SAM requests + payload from it ( as much as needed)
+  my ($self,$content,$flags)=@_;
+  my $return;
+  my $maxsize=(POSIX::BUFSIZ-100);
+  
+  if($self->{state}!=250) {
+    $self->log("Error: SAM::send():  wrong state for send command: Needed:250 Recent:".$self->{state});
+    return 0;
+  }
+  # ok, what can happen?
+  # it could be that $content is far bigger than
+  # POSIX::BUFSIZ; so we need to do a little loop
+  # apart from that sending is in our hand
+  
+  if(length($content) > $maxsize) {
+    $self->{outbuffer}.="STREAM SEND ID=".$self->{streamid}." SIZE=$maxsize\n".substr($content,0,$maxsize);
+    $content=substr($content,$maxsize,length($content));
+  } else {
+    $self->{outbuffer}.="STREAM SEND ID=".$self->{streamid}." SIZE=".length($content)."\n".$content;
+  }
+  
+  if( $self->raw_send()) {
+    return 1;
+  } else {
+    $self->log("Error: SAM::send(): Could not send. Closing Link");
+  }
+}
+
+sub recv {
+  my($self,$varname,$size,$flags)=@_;
+  my $return;
+  my $tunebuffer;
+  my $counter;
+  my $chunk;
+
+
+  # main recv wrapper. We need to invest a few thoughts
+  # for this. To the user it will be like a $socket->recv
+  # (hopefully)
+  # at first some sanity checks
+  if(!$flags) {
+    $flags=0;
+  }
+  
+  $self->{bytestoread}=0;
+  # size must not exceed The posix limit;
+  
+  if(!$size || $size > POSIX::BUFSIZ) {
+    $self->log("Warn: SAM::recv(): Setting buffersize to POSIX::BUFSIZ");
+    $size=POSIX::BUFSIZ;
+  }
+  
+
+  # nobody should call is prior to state 250
+  if($self->{state}!=250) {
+    $self->log("Error: SAM::recv():  wrong state for rcv command: Needed:250 Recent:".$self->{state});
+    return 0;
+  }
+
+
+  # we have a greeting banner left from connect
+  # flush it to the user. This can happen on several services
+  # like smtp/pop3/nntp but not on HTTP and other stuff
+  
+  if($self->{hasbanner}) {
+    
+    #print "D: ".$self->{inbuffer};
+    
+    if(length($self->{inbuffer}) >0 ) {
+      $chunk=substr($self->{inbuffer},0, $size);
+      $self->{hasbanner}=0;
+      substr($self->{inbuffer},0, $size)='';
+      return $chunk;
+    } else { 
+      $self->log("Error: SAM::recv():  Should have a banner but i have empty inbuffer?");
+      return 0;
+    }
+    # should never reach here    
+    return 1;
+  }
+  # when there's something in the inbuffer left
+  # flush it to the user. If the amount of data is bigger than
+  # the userspecified limit, only transfer $size Bytes to the 
+  # client
+  if(length($self->{inbuffer}) > 0) {
+    $chunk=substr($self->{inbuffer},0, $size);
+    substr($self->{inbuffer},0, $size)='';
+    return $chunk;
+  }
+
+  # OK, we got noting in the inbuffer
+  # we'll fetch a new chunk of data and then add the data to the inbuffer
+  # if bytestoread is bigger than POSIX::BUFSIZ we'll internally use 
+  # a loop of reads and fill the buffer til bytestoread is 0
+
+  if(length($self->{inbuffer}) == 0) {
+    # read the first packet
+    if($self->raw_read()) {
+      if($self->parse_sam("STREAM") && ${$self->{samreply}}{REPLY} eq "RECEIVED") {
+        # it's possible that the packet does not contain any payload at all!! 
+	# if this is the case we need 
+	if($self->{inbuffer}=~/^.*$/) {
+          $self->log("Warn: SAM::recv(): Got only only one line from SAM - but i expected some payload too. Calling raw_read again ");
+	  $self->raw_read();
+	}
+	# ok, cut the SAM HEADER from the payload
+        $self->{inbuffer}=substr($self->{inbuffer},(length($self->{inbuffer})-$self->{bytestoread}), length($self->{inbuffer}));
+	$self->log("Debug: SAM::recv(): Recived a Stream Packet and cut the SAM header out");
+	# ok, check if bytestoread is still bigger than our buffersize
+	# this means we can load more. Dangerous loop but well...
+	
+	while(length($self->{inbuffer}) < $self->{bytestoread}) {
+	  # this should definately end some day
+	  $counter++;
+	  if($counter > 10000) {
+            $self->log("Error: SAM::recv(): WTF, could not fill inbuffer as predicted by SAM header");
+            last;
+	  }
+	  # read as long til we have read all of the payload provided by SAM
+	  
+          $self->log("Debug: SAM::recv(): Load another chunk. Buffersize:".length($self->{inbuffer})." / Bytestoread:".$self->{bytestoread} );
+	  $self->raw_read();
+	}
+	
+      } else {
+        $self->log("Error: SAM::recv(): parse_sam() did not succeed. Interupting");
+	delete $self->{inbuffer};
+	return 0;
+      }
+
+    } else {
+      $self->log("Error: SAM::recv(): Could not read from the socket");
+      delete $self->{inbuffer};
+      return 0;
+    }
+
+   
+    $chunk=substr($self->{inbuffer},0, $size);
+    substr($self->{inbuffer},0, $size)='';
+    return $chunk;
+  }
+  
+  return 1;
+  
+}
+
+sub lookup {
+  my($self,$name)=@_;
+  my $return;
+  
+  $self->{outbuffer}="NAMING LOOKUP NAME=$name\n";
+  $return=$self->raw_send();
+ 
+  if($return == 1) {
+    if($self->raw_read()) {
+      if($self->parse_sam("NAMING")) {
+	$self->log("Debug: SAM::lookup(): Naming Lookup successful");
+	delete $self->{inbuffer};
+	delete $self->{outbuffer};
+        return $self->{lookupresult};	
+      }
+    } else {
+      $self->log("Error :SAM::lookup(): NAMING Failed. Cannot read SAM Response");
+      return 0;
+    }
+  }
+
+  if($return == 0) {
+    $self->log("Error :SAM::lookup(): NAMING Failed. Cannot send NAMING String");
+    return 0;
+  }
+
+}
+
+
+sub sam_close {
+  my ($self) =@_;
+  $self->log("Debug: SAM::sam_close(): Closing Socket to SAM");
+  $self->{sock}->close();
+  return 1;
+}
+
+
+sub close {
+  my ($self)=@_;
+  my $return;
+  $self->{outbuffer}.="STREAM CLOSE ID=".$self->{streamid}."\n";
+  $self->log("Debug: SAM::close(): CLosing Stream with id: ".$self->{streamid});
+  $return=$self->raw_send();
+  # well, we do not care wether this worked or not
+  $self->sam_close();
+  return 1;
+}
+
+
+sub connect {
+  my ($self,$destination)=@_;
+  my $return;
+
+  $self->{streamid}= int(rand(200000000));
+  if(length($destination) == 0) {
+    $self->log("Error: SAM::connect(): need I2P destination to connect to with the SAM Bridge");
+    return 0;
+  }
+  
+  $self->{outbuffer}.="STREAM CONNECT ID=".$self->{streamid}." DESTINATION=$destination\n";
+  $return=$self->raw_send();
+ 
+  if($return == 1) {
+    if($self->raw_read()) {
+      if($self->parse_sam("STREAM")) {
+	if(${$self->{samreply}}{REPLY} eq "STATUS") {
+	  $self->{state}=250;
+	  $self->log("Debug: SAM::connect(): State Transition 200 => 250");
+	  # flush the whole inbuffer;
+	  delete $self->{inbuffer};
+	  delete $self->{outbuffer};
+	  return 1;
+	}
+	
+	if(${$self->{samreply}}{REPLY} eq "RECEIVED") {
+	  $self->{state}=250;
+	  $self->log("Debug: SAM::connect(): State Transition 200 => 250. Got a banner");
+          delete $self->{inbuffer};
+
+	  #print "D: toread:".$self->{bytestoread};
+	  #print "D: buffer:".$self->{inbuffer}."\n";
+	  #print "D: buffersize:".length($self->{inbuffer})."\n";
+	  
+	  $self->raw_read();
+	  #print "D: toread:".$self->{bytestoread};
+	  #print "D: buffer:".$self->{inbuffer}."\n";
+	  #print "D: buffersize:".length($self->{inbuffer})."\n";
+
+          $self->{inbuffer}=substr($self->{inbuffer}, 0, $self->{bytestoread});
+	  $self->{hasbanner}=1;
+
+	  #print "D: toread:".$self->{bytestoread};
+	  #print "D: buffer:".$self->{inbuffer}."\n";
+	  #print "D: buffersize:".length($self->{inbuffer})."\n";
+	  
+	  return 1;	
+	}
+	
+      }
+    } else {
+      $self->log("Error: SAM::connect(): STREAM Failed. Cannot read SAM Response");
+      return 0;
+    }
+  }
+
+  if($return == 0) {
+    $self->log("Error: SAM::connect(): STREAM Failed. Cannot send SESSION String");
+    return 0;
+  }
+  
+
+}
+
+
+
+sub log {
+  my($self,$line)=@_;
+  if($line=~/.*\n$/) {
+    chomp $line;
+  }
+  if ( $self->{debug} ) {
+    print LOGFILE "$line\n";
+  }
+  return 1;
+
+}
+
+
diff --git a/apps/sam/perl/samcat.pl b/apps/sam/perl/samcat.pl
deleted file mode 100644
index ba766f75d3449a14e00ef1bc57a9411eda88a3bf..0000000000000000000000000000000000000000
--- a/apps/sam/perl/samcat.pl
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/perl
-
-use Net::SAM::RawSession;
-use Net::SAM::DatagramSession;
-
-$sam=Net::SAM::DatagramSession->new($ARGV[0], "BOTH", "tunnels.depthInbound=0");
-print "Connected? " . $sam->connected() . "\n";
-
-$me = $sam->lookup("ME");
-print "Sending to $me.\n";
-$sam->send($me,"fooquux");
-
-$sam->readprocess();
-($source, $message) = @{ $sam->receive() };
-print "$source -- $message"; 
-
-
-