public void run()
	{
		boolean newPeer;
		generateHandshake();
		byte[] handshakeResponse;
		
		// this happens when we are the ones who want to download
		if (s == null)
		{
			newPeer = false;
			if (getConnection())
			{
				System.out.println("got connection to " + this.ip);
				pMgr.addConnectedPeer(this);
			}
			else
			{
				System.out.println("couldnt get connection to " + this.ip);
				return;
			}
			if (!sendAndValidateHandshake(newPeer))
			{
				System.err.println("couldn't verify handshake with " + this.ip);
				pMgr.removeConnectedPeer(this);
				return;
			}
		}
		// happens when a peer has connected to us
		else
		{
			newPeer = true;
			if (getStreams())
			{
				System.out.println("acquired streams for incoming connection " + this.ip);
				pMgr.addConnectedPeer(this);
			}
			else
			{
				// if can't get the streams, then close the socket.
				System.out.println("couldn't get streams for " + this.ip);
				try 
				{
					this.s.close();
				} 
				catch (IOException e) 
				{
					e.printStackTrace();
				}
				return;
			}
			handshakeResponse = getHandshakeResponse();
			if (!verifyResponse(handshakeResponse, newPeer))
			{
				System.err.println("couldn't verify handshake with " + this.ip);
				pMgr.removeConnectedPeer(this);
				return;
			}
			else
			{
				System.out.println("verified response from " + this.ip);
			}
			sendHandshake();	
		}
		
		
		BitfieldMessage bm =  new BitfieldMessage(pMgr.getBitfieldLength(), pMgr.getBitfield());
		pMgr.sendMessage(bm, this);
		
		while (continueRunning)
		{
			try
			{
				Message m = Message.receive(inStream);
				pMgr.acceptMessage(m, this);
			}
			catch (IOException e)
			{
				continueRunning = false;
			}
		}
	}