@Transactional
  public Usuario changeSenha(Long usuarioId, String newSenha) {
    Usuario usuario = findOne(usuarioId);

    if (usuario == null) {
      throw new HttpException(EXCEPTION_USUARIO_NOT_FOUND, HttpStatus.NOT_ACCEPTABLE);
    }

    usuario.setSenha(newSenha);

    return saveAsUpdate(usuario, true);
  }
  @Transactional(readOnly = true)
  private void validateAsInsert(Usuario usuario, boolean ignorePessoa) {
    if (ignorePessoa) {
      validateIgnoringIdAndPessoa(usuario);
    } else {
      validateIgnoringId(usuario);
    }

    if (usuario.getUsuarioId() != null) {
      throw new HttpException(EXCEPTION_USUARIO_USUARIO_ID_MUST_BE_NULL, HttpStatus.NOT_ACCEPTABLE);
    }

    if (findByApelido(usuario.getApelido()) != null) {
      throw new HttpException(
          EXCEPTION_USUARIO_APELIDO_IS_ALREADY_IN_USE, HttpStatus.NOT_ACCEPTABLE);
    }
  }
  @Transactional(readOnly = true)
  public void validateIgnoringIdByEstabelecimento(Usuario usuario) {
    validateIgnoringId(usuario);

    if (estabelecimentoService.findOne(usuario.getPessoa().getPessoaId()) == null) {
      throw new HttpException(
          EXCEPTION_USUARIO_PESSOA_MUST_BE_ESTABELECIMENTO, HttpStatus.NOT_ACCEPTABLE);
    }
  }
  @Transactional(readOnly = true)
  public void validateIgnoringId(Usuario usuario) {
    validateIgnoringIdAndPessoa(usuario);

    if (usuario.getPessoa() != null) {
      if (usuario.getPessoa().getPessoaId() == null) {
        throw new HttpException(
            EXCEPTION_USUARIO_PESSOA_PESSOA_ID_MUST_NOT_BE_NULL, HttpStatus.NOT_ACCEPTABLE);
      }

      Pessoa foundPessoa = pessoaService.findOne(usuario.getPessoa().getPessoaId());

      if (foundPessoa == null) {
        throw new HttpException(EXCEPTION_USUARIO_PESSOA_NOT_FOUND, HttpStatus.NOT_ACCEPTABLE);
      }

      usuario.setPessoa(foundPessoa);
    }
  }
  @Transactional
  public Usuario changeSenha(Long usuarioId, String oldSenha, String newSenha) {
    Usuario usuario = findOne(usuarioId);

    if (usuario == null) {
      throw new HttpException(EXCEPTION_USUARIO_NOT_FOUND, HttpStatus.NOT_ACCEPTABLE);
    }

    if (usuario.getSenha().equals(encryptSenha(oldSenha))) {
      validateSenha(newSenha);

      usuario.setSenha(newSenha);

      return saveAsUpdate(usuario, true);
    } else {
      throw new HttpException(
          EXCEPTION_USUARIO_OLD_SENHA_DOES_NOT_MATCH, HttpStatus.NOT_ACCEPTABLE);
    }
  }
  @Transactional
  public Usuario saveAsUpdateByEstabelecimento(Long usuarioId, Usuario usuario, boolean encrypt) {
    if (usuarioRepository.findOne(usuarioId) != null) {
      usuario.setUsuarioId(usuarioId);

      return saveAsUpdateByEstabelecimento(usuario, encrypt);
    } else {
      throw new HttpException(EXCEPTION_USUARIO_NOT_FOUND, HttpStatus.NOT_ACCEPTABLE);
    }
  }
  @Transactional(readOnly = true)
  public void validateIgnoringIdAndPessoa(Usuario usuario) {
    if (usuario == null) {
      throw new HttpException(EXCEPTION_USUARIO_MUST_NOT_BE_NULL, HttpStatus.NOT_ACCEPTABLE);
    }

    if (usuario.getStatus() == null) {
      throw new HttpException(EXCEPTION_USUARIO_STATUS_MUST_NOT_BE_NULL, HttpStatus.NOT_ACCEPTABLE);
    }

    if (StringHelper.isBlank(usuario.getApelido())) {
      throw new HttpException(
          EXCEPTION_USUARIO_APELIDO_MUST_NOT_BE_EMPTY, HttpStatus.NOT_ACCEPTABLE);
    }

    if (usuario.getApelido().length() > 45) {
      throw new HttpException(
          EXCEPTION_USUARIO_APELIDO_MUST_NOT_BE_BIGGER_THAN_45_CHARACTERS,
          HttpStatus.NOT_ACCEPTABLE);
    }

    if (!usuario.getApelido().matches(Constants.TEXT_PATTERN_APELIDO)) {
      throw new HttpException(
          EXCEPTION_USUARIO_APELIDO_MUST_CONTAINS_ONLY_LETTERS_NUMBERS_UNDERLINES_DASHES_AND_POINTS,
          HttpStatus.NOT_ACCEPTABLE);
    }

    validateSenha(usuario.getSenha());

    if (usuario.getPerfis() != null) {
      for (int i = 0; i < usuario.getPerfis().size(); i++) {
        for (int j = 0; j < usuario.getPerfis().size(); j++) {
          if (j != i) {
            if (usuario.getPerfis().get(i) == usuario.getPerfis().get(j)) {
              throw new HttpException(
                  EXCEPTION_USUARIO_MUST_NOT_CONTAINS_DUPLICATED_PERFIS, HttpStatus.NOT_ACCEPTABLE);
            }
          }
        }
      }
    }
  }
  public boolean isInPerfis(Usuario usuario, Usuario.Perfil... perfis) {
    for (Usuario.Perfil usuarioPerfil : perfis) {
      for (Usuario.Perfil perfil : usuario.getPerfis()) {
        if (usuarioPerfil == perfil) {
          return true;
        }
      }
    }

    return false;
  }
  public static boolean hasPerfil(Usuario usuario, Usuario.Perfil perfil) {
    // null safe for jsp :-)
    if (usuario != null) {
      for (Usuario.Perfil usuarioPerfil : usuario.getPerfis()) {
        if (usuarioPerfil == perfil) {
          return true;
        }
      }
    }

    return false;
  }
  @Transactional(readOnly = true)
  private void validateAsUpdate(Usuario usuario, boolean ignorePessoa) {
    if (ignorePessoa) {
      validateIgnoringIdAndPessoa(usuario);
    } else {
      validateIgnoringId(usuario);
    }

    if (usuario.getUsuarioId() == null) {
      throw new HttpException(
          EXCEPTION_USUARIO_USUARIO_ID_MUST_NOT_BE_NULL, HttpStatus.NOT_ACCEPTABLE);
    }

    if (findOne(usuario.getUsuarioId()) == null) {
      throw new HttpException(EXCEPTION_USUARIO_NOT_FOUND, HttpStatus.NOT_ACCEPTABLE);
    }

    Usuario foundUsuarioByApelido = findByApelido(usuario.getApelido());

    if (foundUsuarioByApelido != null) {
      if (!foundUsuarioByApelido.getUsuarioId().equals(usuario.getUsuarioId())) {
        throw new HttpException(
            EXCEPTION_USUARIO_APELIDO_IS_ALREADY_IN_USE, HttpStatus.NOT_ACCEPTABLE);
      }
    }
  }
  public Usuario encrypt(Usuario decryptedUsuario) {
    decryptedUsuario.setSenha(encryptSenha(decryptedUsuario.getSenha()));

    return decryptedUsuario;
  }