 
 			@timers.push(setInterval(@_updateCoordinates, 7500))
 
-		# Is called when a peers disconnects. If that peer was 
-		# our parent, we pick a new parent.
-		#
-		# @param peer [Peer] the peer that disconnects
-		#
-		_onPeerDisconnect: ( peer ) =>	
-			if peer is @getParent()
-				candidates = _(@getPeers()).filter( ( p ) -> p.isSuperNode )
-				@_pickParent(candidates)
-
-			super(peer)
-
-		# Removes a peer from the peer list
-		#
-		# @param peer [Peer] the peer to remove
-		#
-		removePeer: (peer) ->
-			super(peer)
+		# Change a SuperNode state of a node
+		#
+		# @param superNode [boolean] SuperNode state
+		#
+		setSuperNode: ( superNode = true ) =>
+			if superNode is not @isSuperNode
+				if not superNode and @getSiblings().length is 0
+					return
+				@server.emit('setSuperNode', superNode)
+				@trigger('setSuperNode', superNode) # App is listening
+				@broadcast('peer.setSuperNode', @id, superNode)
+				@isSuperNode = superNode
+				if superNode
+					@_triggerStaySuperNodeTimeout()
+				else
+					for sibling in @getSiblings()
+						@removeSibling(sibling)
+					@_pickParent()		
+
+		# Sets a peer as the parent node of this node.
+		#
+		# @param peer [Peer] the peer to set as parent
+		# @param callback [function] is called with a parameter if a node is accepted or not
+		#
+		setParent: ( peer, callback ) ->
+			peer.query('peer.requestParent', @id, ( accepted ) =>
+				if accepted
+					@_parent?.emit('peer.abandonParent')
+					@_parent?.role = Peer.Role.None
+					peer.role = Peer.Role.Parent
+					@_parent = peer
+
+				callback(accepted)
+			)
+
+		# Returns the parent peer of this node.
+		#
+		# @return [Peer] the parent peer
+		#
+		getParent: ( ) ->
+			return @_parent
+
+		# Adds a peer as child node.
+		#
+		# @param peer [Peer] the peer to add as child
+		#
+		addChild: ( peer ) ->
+			if peer is @_parent
+				@_parent = null
+			peer.role = Peer.Role.Child
+			if @getChildren().length > 4
+				_(@generateToken).defer()
+
+		# Removes a peer as child node. Does not automatically close 
+		# the connection but will make it a normal peer.
+		#
+		# @param peer [Peer] the peer to remove as child
+		#
+		removeChild: ( peer ) ->
+			peer.role = Peer.Role.None
 			@_triggerStaySuperNodeTimeout()
+
+		# Returns a child specified by an id
+		#
+		# @param id [String] the id of the requested child
+		# @return [Peer] the child
+		#
+		getChild: ( id ) ->
+			return @getPeer(id, Peer.Role.Child)
+
+		# Returns all current child nodes.
+		#
+		# @return [Array<Peer>] an array of all child nodes
+		#
+		getChildren: ( ) ->
+			return @getPeers(Peer.Role.Child)
+
+		# Adds a peer as sibling node.
+		#
+		# @param peer [Peer] the peer to add as sibling
+		#
+		addSibling: ( peer, instantiate = true ) ->
+			if peer is @_parent
+				@_parent = null
+
+			peer.role = Peer.Role.Sibling
+			if instantiate
+				peer.emit('peer.addSibling', @id)
+
+		# Removes a peer as sibling node. Does not automatically close 
+		# the connection but will make it a normal peer.
+		#
+		# @param peer [Peer] the peer to remove as sibling
+		#
+		removeSibling: ( peer ) ->
+			peer.role = Peer.Role.None
+
+		# Returns a sibling specified by an id
+		#
+		# @param id [String] the id of the requested sibling
+		# @return [Peer] the sibling
+		#
+		getSibling: ( id ) ->
+			return @getPeer(id, Peer.Role.Sibling)
+
+		# Returns all current sibling nodes.
+		#
+		# @return [Array<Peer>] an array of all sibling nodes
+		#
+		getSiblings: ( ) ->
+			return @getPeers(Peer.Role.Sibling)
 
 		# Responds to a request
 		#

				@setSuperNode(true)

			return tokenMagnitude
		
		# Is called when a token magnitude is calculated. A supernode selects his 
		# best child as candidate for the token
		#

						bestCandidate = child
				if child?
					@emitTo(token.nodeId, 'token.candidate', distance, child.id)

		# Is called when a node holding a token, receives other candidate nodes for the token
		#
		# @param peer [Peer] The last routing peer
