@Nullable
  @Override
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Utils.Log("MessageFragment onCreateView called");
    View view = inflater.inflate(R.layout.fragment_messages, container, false);
    messageList = (ListView) view.findViewById(R.id.messages_list);
    messages = dbManager.getMessages(conversation.getUsername());
    adapter =
        new MessagesAdapter(
            getActivity(),
            messages,
            dbManager.getUsername(),
            conversation.getUsername(),
            conversationPass);
    messageList.setAdapter(adapter);

    messageList.setOnItemLongClickListener(messageLongClicked);

    if (savedInstanceState == null) {
      messageList.setSelection(adapter.getCount() - 6);
    }

    sendMessage = (Button) view.findViewById(R.id.btn_message_send);
    sendMessage.setOnClickListener(sendClicked);
    messageText = (MaterialEditText) view.findViewById(R.id.user_message_text);
    return view;
  }
  @Override
  public void onSaveInstanceState(Bundle outState) {

    outState.putString("username", conversation.getUsername());
    outState.putInt("_id", conversation.getId());
    outState.putInt("unreadMessages", conversation.getUnreadMessages());

    super.onSaveInstanceState(outState);
  }
        @Override
        public void onClick(View view) {

          Utils.Log("Send clicked");

          // If the message field is not empty
          if (!messageText.getText().toString().isEmpty()) {

            final Message message = new Message();
            message.setSender(username);
            message.setRecipient(conversation.getUsername());

            // If DHKE was completed and a key exists
            if (!dbManager.getAESKey(conversation.getUsername()).isEmpty()) {
              String signature = "";
              String key = dbManager.getAESKey(conversation.getUsername());
              byte[] iv = Crypto.GenerateRandomIV();
              final String plainText = messageText.getText().toString();
              final String cipherText = Crypto.AESencrypt(key, plainText, iv);
              final String base64IV = Base64.encodeToString(iv, Base64.NO_WRAP);

              try {
                PrivateKey RSAKeySign =
                    Crypto.RSAStringToPrivateKey(dbManager.getRSAKeySignaturePrivate());

                signature =
                    Base64.encodeToString(
                        Crypto.RSASign(Base64.decode(cipherText, Base64.NO_WRAP), RSAKeySign),
                        Base64.NO_WRAP);

              } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
              } catch (InvalidKeySpecException e) {
                e.printStackTrace();
              } catch (NoSuchProviderException e) {
                e.printStackTrace();
              } catch (InvalidKeyException e) {
                e.printStackTrace();
              } catch (SignatureException e) {
                e.printStackTrace();
              }

              message.setMessage(cipherText);
              message.setIv(base64IV);
              message.setSignature(signature);

              new HttpHandler() {
                @Override
                public HttpUriRequest getHttpRequestMethod() {
                  HttpPost httpPost = new HttpPost(Utils.SERVER_SEND_MESSAGE);

                  List<NameValuePair> nameValuePairs = new ArrayList<>();
                  nameValuePairs.add(new BasicNameValuePair("sender", message.getSender()));
                  nameValuePairs.add(new BasicNameValuePair("recipient", message.getRecipient()));
                  nameValuePairs.add(new BasicNameValuePair("message", message.getMessage()));
                  nameValuePairs.add(new BasicNameValuePair("iv", message.getIv()));
                  nameValuePairs.add(new BasicNameValuePair("signature", message.getSignature()));

                  try {
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                  } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                  }

                  return httpPost;
                }

                @Override
                public void onResponse(String result) {
                  Utils.Log("HttpResult: " + result);

                  if (conversation.isEncrypted().equals("true")) {
                    message.setMessage(
                        Crypto.AESencrypt(
                            conversationPass,
                            plainText,
                            Base64.decode(message.getIv(), Base64.NO_WRAP)));
                    message.setEncrypted(true);

                    dbManager.addMessage(message);

                    message.setEncrypted(false);
                    message.setMessage(plainText);

                    messages.add(message);
                    adapter.notifyDataSetChanged();

                  } else {
                    message.setMessage(plainText);
                    message.setEncrypted(false);

                    dbManager.addMessage(message);

                    messages.add(message);
                    adapter.notifyDataSetChanged();
                  }

                  messageList.setSelection(messages.size() + 1);
                }
              }.execute();

              messageText.setText("");

            }

            // DHKE was not complete yet, store messages unencrypted temporarily
            // and then encrypt and send them once the exchange is complete
            else {
              message.setEncrypted(false);
              message.setMessage(messageText.getText().toString());
              message.setIv(Base64.encodeToString(Crypto.GenerateRandomIV(), Base64.NO_WRAP));

              dbManager.addMessage(message);

              messages.add(message);
              adapter.notifyDataSetChanged();

              messageList.setSelection(adapter.getCount() - 1);
              messageText.setText("");
            }
          }
        }