docs: @SuppressWarnings({ "rawtypes", "unchecked" })
      public int login(Task task, String strUserName, String strPassword, String strDomain)
      {
          boolean bCreateServer = false;
          if ((this.getProperty(Params.REMOTE_HOST) != null) && (this.getProperty(Params.REMOTE_HOST).length() > 0))
              bCreateServer = true;
          org.jbundle.thin.base.remote.RemoteTask remoteTask = (org.jbundle.thin.base.remote.RemoteTask)this.getRemoteTask(null, strUserName, bCreateServer);
          if (remoteTask == null)
          {
              if (task != null)
                  return task.setLastError(this.getResources("Error", true).getString("User remote session does not exist"));
              return Constants.ERROR_RETURN;
          }
          try {
              Map<String,Object> mapLoginInfo = remoteTask.login(strUserName, strPassword, strDomain);
              String strSecurityMap = (String)mapLoginInfo.get(Params.SECURITY_MAP);
              Map<String,Object> mapReturnParams = (Map)mapLoginInfo.get(Params.USER_PROPERTIES);      
  
              if (this.getSystemRecordOwner() != null)
                  this.getSystemRecordOwner().setProperties(mapReturnParams); // Thick implementation
              else
              {
                  if (this.getProperties() == null)
                      this.setProperties(mapReturnParams);    // Thin implementation
                  else
                      this.getProperties().putAll(mapReturnParams);
              }
              if (Util.isNumeric(strUserName))
                  strUserName = null;
              if (mapReturnParams.get(Params.USER_NAME) != null)
                  strUserName = (String)mapReturnParams.get(Params.USER_NAME);
              this.setProperty(Params.USER_NAME, strUserName);
              this.setProperty(Params.USER_ID, (String)mapReturnParams.get(Params.USER_ID));
              this.setProperty(Params.AUTH_TOKEN, (String)mapReturnParams.get(Params.AUTH_TOKEN)); // Save the remote authorization token
              this.setProperty(Params.CONTACT_ID, (String)mapReturnParams.get(Params.CONTACT_ID));
              this.setProperty(Params.CONTACT_TYPE, (String)mapReturnParams.get(Params.CONTACT_TYPE)); // Save the remote authorization token
              
              this.setProperty(Params.SECURITY_MAP, strSecurityMap);
              this.setProperty(Params.SECURITY_LEVEL, ((strPassword == null) || (strPassword.length() == 0)) ? Integer.toString(Constants.LOGIN_USER) : Integer.toString(Constants.LOGIN_AUTHENTICATED));
              if (("1"/*DBConstants.ANON_USER_ID*/.equals(this.getProperty(Params.USER_ID)))
                      || (this.getProperty(Params.USER_ID) == null))
                  this.setProperty(Params.SECURITY_LEVEL, Integer.toString(Constants.LOGIN_USER));   // Special case - If user is anonymous, level is always anonymous
              
              return Constants.NORMAL_RETURN;
          } catch (RemoteException ex) {
              if (task != null)
              {
              	String message = ex.getMessage();
              	if (ex.getCause() != null)
              		message = ex.getCause().getMessage();
                  return task.setLastError(message);
              }
              return Constants.ERROR_RETURN;            
          }
      }