private void handleInitRequest(InitRequest msg) throws IOException
	{   
        BootstrapList bootstrapList = null;
		CAMessage response = null;
		String userId = msg.getUserId();
		
		//stub method, it should implement the various id verification policies
		verifyIdentity(userId);
		
		//build the bootstrap list
		List<Contact> bootList = new LinkedList<Contact>();
		synchronized (ca.getContactList()) //TODO: eliminare???
		{
			int bootListSize = Math.min(ca.getContactList().size(), BOOT_LIST_SIZE);
			for (int i=0; i<bootListSize; i++)
			{
				bootList.add(ca.getContactList().get(i));
			}
			bootstrapList = new BootstrapList(bootList, true);
			try
			{
				//sign bootstrap list
				BootstrapListContent cont = bootstrapList.getContent();
				byte[] signature = ca.getSecurityAgent().sign(cont);
				bootstrapList.setSignature(signature);
			}
			catch (SignatureException e)
			{
				response = ca.getMessageFactory().createErrorMessage(ca.getUserId(), msg.getMessageId(), "Can't sign bootstrap list. Retry later");
				return;
			}
		}
		
		AuthNodeId authId = ca.getRegisteredNodeData().get(userId);
		if (authId != null //there is an existent authNodeId...
			&& authId.getContent().getExpireTime() > System.currentTimeMillis()) //...and it is still valid
		{	
			if (msg.getPublicKey().equals(authId.getContent().getKey()))
			{
				response = ca.getMessageFactory().createInitResponse(ca.getUserId(), msg.getMessageId(), authId, bootstrapList);
			}
			else
			{
				response = ca.getMessageFactory().createErrorMessage(ca.getUserId(), msg.getMessageId(), "Error. Key mismatch");
			}
		}
		else
		{
			try
			{
				// generate a new AuthNodeId
				PublicKey userPublicKey = msg.getPublicKey();

				NodeId userNodeId = ca.genNodeId();
					
				long expireTime = System.currentTimeMillis() + Long.parseLong(PropFinder.get(Settings.AUTH_NODE_ID_DURATION));
				AuthNodeId userAuthNodeId = new AuthNodeId(userNodeId,userPublicKey,userId,expireTime);
				
				try
				{
					//sign authNodeId
					AuthNodeIdContent cont = userAuthNodeId.getContent();
					byte[] signature = ca.getSecurityAgent().sign(cont);
					userAuthNodeId.setSignature(signature);
				}
				catch (SignatureException e)
				{
					response = ca.getMessageFactory().createErrorMessage(ca.getUserId(), msg.getMessageId(), "Can't sign authNodeId. Retry later");
					return;
				}
				// store the generated AuthNodeId
				ca.getRegisteredNodeData().put(userId, userAuthNodeId);
			
				// build a response  message
				response = ca.getMessageFactory().createInitResponse(ca.getUserId(), msg.getMessageId(), userAuthNodeId, bootstrapList);
				
				// add the contact to the CA contact list
				if (msg.getUDPAddress() != null)
				{
					ca.addContact(userNodeId, msg.getUDPAddress());
				}
			}
			catch (Exception e)
			{
				response = ca.getMessageFactory().createErrorMessage(ca.getUserId(), msg.getMessageId(), "Error in request processing");
			}
		}
		//send message
		send(response);
	}