@Override
  public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    config = ParseLoginConfig.fromBundle(getArguments(), getActivity());

    View v = inflater.inflate(R.layout.com_parse_ui_parse_login_fragment, parent, false);
    ImageView appLogo = (ImageView) v.findViewById(R.id.app_logo);
    parseLogin = v.findViewById(R.id.parse_login);
    usernameField = (EditText) v.findViewById(R.id.login_username_input);
    passwordField = (EditText) v.findViewById(R.id.login_password_input);
    parseLoginHelpButton = (Button) v.findViewById(R.id.parse_login_help);
    parseLoginButton = (Button) v.findViewById(R.id.parse_login_button);
    parseSignupButton = (Button) v.findViewById(R.id.parse_signup_button);
    facebookLoginButton = (Button) v.findViewById(R.id.facebook_login);
    twitterLoginButton = (Button) v.findViewById(R.id.twitter_login);

    if (appLogo != null && config.getAppLogo() != null) {
      appLogo.setImageResource(config.getAppLogo());
    }
    if (allowParseLoginAndSignup()) {
      setUpParseLoginAndSignup();
    }
    if (allowFacebookLogin()) {
      setUpFacebookLogin();
    }
    if (allowTwitterLogin()) {
      setUpTwitterLogin();
    }
    return v;
  }
  private boolean allowParseLoginAndSignup() {
    if (!config.isParseLoginEnabled()) {
      return false;
    }

    if (usernameField == null) {
      debugLog(R.string.com_parse_ui_login_warning_layout_missing_username_field);
    }
    if (passwordField == null) {
      debugLog(R.string.com_parse_ui_login_warning_layout_missing_password_field);
    }
    if (parseLoginButton == null) {
      debugLog(R.string.com_parse_ui_login_warning_layout_missing_login_button);
    }
    if (parseSignupButton == null) {
      debugLog(R.string.com_parse_ui_login_warning_layout_missing_signup_button);
    }
    if (parseLoginHelpButton == null) {
      debugLog(R.string.com_parse_ui_login_warning_layout_missing_login_help_button);
    }

    boolean result =
        (usernameField != null)
            && (passwordField != null)
            && (parseLoginButton != null)
            && (parseSignupButton != null)
            && (parseLoginHelpButton != null);

    if (!result) {
      debugLog(R.string.com_parse_ui_login_warning_disabled_username_password_login);
    }
    return result;
  }
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {

    Bundle args = getArguments();
    config = ParseLoginConfig.fromBundle(args, getActivity());

    minPasswordLength = DEFAULT_MIN_PASSWORD_LENGTH;
    if (config.getParseSignupMinPasswordLength() != null) {
      minPasswordLength = config.getParseSignupMinPasswordLength();
    }

    String username = args.getString(USERNAME);
    String password = args.getString(PASSWORD);

    View v = inflater.inflate(R.layout.com_parse_ui_parse_signup_fragment, parent, false);
    v.setBackgroundColor(Color.parseColor("#FFFFFF"));
    ImageView appLogo = (ImageView) v.findViewById(R.id.app_logo);
    usernameField = (EditText) v.findViewById(R.id.signup_username_input);
    passwordField = (EditText) v.findViewById(R.id.signup_password_input);
    confirmPasswordField = (EditText) v.findViewById(R.id.signup_confirm_password_input);
    emailField = (EditText) v.findViewById(R.id.signup_email_input);
    nameField = (EditText) v.findViewById(R.id.signup_name_input);
    if (!config.isParseSignupNameFieldEnabled()) {
      nameField.setVisibility(View.INVISIBLE);
    }
    createAccountButton = (Button) v.findViewById(R.id.create_account);

    usernameField.setText(username);
    passwordField.setText(password);

    if (appLogo != null && config.getAppLogo() != null) {
      appLogo.setImageResource(config.getAppLogo());
    }

    if (config.isParseLoginEmailAsUsername()) {
      usernameField.setHint(R.string.com_parse_ui_email_input_hint);
      usernameField.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
      if (emailField != null) {
        emailField.setVisibility(View.GONE);
      }
    }

    if (config.getParseSignupSubmitButtonText() != null) {
      createAccountButton.setText(config.getParseSignupSubmitButtonText());
    }
    createAccountButton.setOnClickListener(this);

    return v;
  }
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    config = ParseLoginConfig.fromBundle(getArguments(), getActivity());

    View v = inflater.inflate(R.layout.com_parse_ui_parse_login_fragment, parent, false);
    ImageView appLogo = (ImageView) v.findViewById(R.id.app_logo);
    parseLogin = v.findViewById(R.id.parse_login);
    usernameField = (AutoCompleteTextView) v.findViewById(R.id.login_username_input);
    passwordField = (EditText) v.findViewById(R.id.login_password_input);
    parseLoginHelpButton = (Button) v.findViewById(R.id.parse_login_help);
    parseLoginButton = (Button) v.findViewById(R.id.parse_login_button);
    parseSignupButton = (Button) v.findViewById(R.id.parse_signup_button);
    facebookLoginButton = (Button) v.findViewById(R.id.facebook_login);
    twitterLoginButton = (Button) v.findViewById(R.id.twitter_login);

    accounts = AccountManager.get(getActivity()).getAccounts();
    Set<String> emailSet = new HashSet<String>();
    for (Account account : accounts) {
      if (EMAIL_PATTERN.matcher(account.name).matches()) {
        emailSet.add(account.name);
      }
    }
    usernameField.setAdapter(
        new ArrayAdapter<String>(
            getActivity(),
            android.R.layout.simple_dropdown_item_1line,
            new ArrayList<String>(emailSet)));

    if (appLogo != null && config.getAppLogo() != null) {
      appLogo.setImageResource(config.getAppLogo());
    }
    if (allowParseLoginAndSignup()) {
      setUpParseLoginAndSignup();
    }
    if (allowFacebookLogin()) {
      setUpFacebookLogin();
    }
    if (allowTwitterLogin()) {
      setUpTwitterLogin();
    }
    return v;
  }
  private boolean allowTwitterLogin() {
    if (!config.isTwitterLoginEnabled()) {
      return false;
    }

    if (twitterLoginButton == null) {
      debugLog(R.string.com_parse_ui_login_warning_disabled_twitter_login);
      return false;
    } else {
      return true;
    }
  }
  private boolean allowFacebookLogin() {
    if (!config.isFacebookLoginEnabled()) {
      return false;
    }

    if (facebookLoginButton == null) {
      debugLog(R.string.com_parse_ui_login_warning_disabled_facebook_login);
      return false;
    } else {
      return true;
    }
  }
  private void setUpParseLoginAndSignup() {
    parseLogin.setVisibility(View.VISIBLE);

    if (config.isParseLoginEmailAsUsername()) {
      usernameField.setHint(R.string.com_parse_ui_email_input_hint);
      usernameField.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
    }

    if (config.getParseLoginButtonText() != null) {
      parseLoginButton.setText(config.getParseLoginButtonText());
    }

    parseLoginButton.setOnClickListener(
        new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            String username = usernameField.getText().toString();
            String password = passwordField.getText().toString();

            if (username.length() == 0) {
              if (config.isParseLoginEmailAsUsername()) {
                showToast(R.string.com_parse_ui_no_email_toast);
              } else {
                showToast(R.string.com_parse_ui_no_username_toast);
              }
            } else if (password.length() == 0) {
              showToast(R.string.com_parse_ui_no_password_toast);
            } else {
              loadingStart(true);
              ParseUser.logInInBackground(
                  username,
                  password,
                  new LogInCallback() {
                    @Override
                    public void done(ParseUser user, ParseException e) {
                      if (isActivityDestroyed()) {
                        return;
                      }

                      if (user != null) {
                        loadingFinish();
                        loginSuccess();
                      } else {
                        loadingFinish();
                        if (e != null) {
                          debugLog(
                              getString(R.string.com_parse_ui_login_warning_parse_login_failed)
                                  + e.toString());
                          if (e.getCode() == ParseException.OBJECT_NOT_FOUND) {
                            if (config.getParseLoginInvalidCredentialsToastText() != null) {
                              showToast(config.getParseLoginInvalidCredentialsToastText());
                            } else {
                              showToast(
                                  R.string.com_parse_ui_parse_login_invalid_credentials_toast);
                            }
                            passwordField.selectAll();
                            passwordField.requestFocus();
                          } else {
                            showToast(R.string.com_parse_ui_parse_login_failed_unknown_toast);
                          }
                        }
                      }
                    }
                  });
            }
          }
        });

    if (config.getParseSignupButtonText() != null) {
      parseSignupButton.setText(config.getParseSignupButtonText());
    }

    parseSignupButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            String username = usernameField.getText().toString();
            String password = passwordField.getText().toString();

            loginFragmentListener.onSignUpClicked(username, password);
          }
        });

    if (config.getParseLoginHelpText() != null) {
      parseLoginHelpButton.setText(config.getParseLoginHelpText());
    }

    parseLoginHelpButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            loginFragmentListener.onLoginHelpClicked();
          }
        });
  }
  @Override
  public void onClick(View v) {
    String username = usernameField.getText().toString();
    String password = passwordField.getText().toString();
    String passwordAgain = confirmPasswordField.getText().toString();

    String email = null;
    if (config.isParseLoginEmailAsUsername()) {
      email = usernameField.getText().toString();
    } else if (emailField != null) {
      email = emailField.getText().toString();
    }

    String name = null;
    if (nameField != null) {
      name = nameField.getText().toString();
    }

    if (username.length() == 0) {
      if (config.isParseLoginEmailAsUsername()) {
        showToast(R.string.com_parse_ui_no_email_toast);
      } else {
        showToast(R.string.com_parse_ui_no_username_toast);
      }
    } else if (password.length() == 0) {
      showToast(R.string.com_parse_ui_no_password_toast);
    } else if (password.length() < minPasswordLength) {
      showToast(
          getResources()
              .getQuantityString(
                  R.plurals.com_parse_ui_password_too_short_toast,
                  minPasswordLength,
                  minPasswordLength));
    } else if (passwordAgain.length() == 0) {
      showToast(R.string.com_parse_ui_reenter_password_toast);
    } else if (!password.equals(passwordAgain)) {
      showToast(R.string.com_parse_ui_mismatch_confirm_password_toast);
      confirmPasswordField.selectAll();
      confirmPasswordField.requestFocus();
    } else if (email != null && email.length() == 0) {
      showToast(R.string.com_parse_ui_no_email_toast);
    } else if (name != null && name.length() == 0) {
      showToast(R.string.com_parse_ui_no_name_toast);
    } else {
      ParseUser user = new ParseUser();

      // Set standard fields
      user.setUsername(username);
      user.setPassword(password);
      user.setEmail(email);

      // Set additional custom fields only if the user filled it out
      if (name.length() != 0) {
        user.put(USER_OBJECT_NAME_FIELD, name);
      }

      loadingStart();
      user.signUpInBackground(
          new SignUpCallback() {

            @Override
            public void done(ParseException e) {
              if (isActivityDestroyed()) {
                return;
              }

              if (e == null) {
                loadingFinish();
                signupSuccess();
              } else {
                loadingFinish();
                if (e != null) {
                  debugLog(
                      getString(R.string.com_parse_ui_login_warning_parse_signup_failed)
                          + e.toString());
                  switch (e.getCode()) {
                    case ParseException.INVALID_EMAIL_ADDRESS:
                      showToast(R.string.com_parse_ui_invalid_email_toast);
                      break;
                    case ParseException.USERNAME_TAKEN:
                      showToast(R.string.com_parse_ui_username_taken_toast);
                      break;
                    case ParseException.EMAIL_TAKEN:
                      showToast(R.string.com_parse_ui_email_taken_toast);
                      break;
                    default:
                      showToast(R.string.com_parse_ui_signup_failed_unknown_toast);
                  }
                }
              }
            }
          });
    }
  }
  private void setUpTwitterLogin() {
    twitterLoginButton.setVisibility(View.VISIBLE);

    if (config.getTwitterLoginButtonText() != null) {
      twitterLoginButton.setText(config.getTwitterLoginButtonText());
    }

    twitterLoginButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            loadingStart(false); // Twitter login pop-up already has a spinner
            ParseTwitterUtils.logIn(
                getActivity(),
                new LogInCallback() {
                  @Override
                  public void done(ParseUser user, ParseException e) {
                    if (isActivityDestroyed()) {
                      return;
                    }

                    if (user == null) {
                      loadingFinish();
                      if (e != null) {
                        showToast(R.string.com_parse_ui_twitter_login_failed_toast);
                        debugLog(
                            getString(R.string.com_parse_ui_login_warning_twitter_login_failed)
                                + e.toString());
                      }
                    } else if (user.isNew()) {
                      Twitter twitterUser = ParseTwitterUtils.getTwitter();
                      if (twitterUser != null && twitterUser.getScreenName().length() > 0) {
                        /*
                          To keep this example simple, we put the users' Twitter screen name
                          into the name field of the Parse user object. If you want the user's
                          real name instead, you can implement additional calls to the
                          Twitter API to fetch it.
                        */
                        user.put(USER_OBJECT_NAME_FIELD, twitterUser.getScreenName());
                        user.saveInBackground(
                            new SaveCallback() {
                              @Override
                              public void done(ParseException e) {
                                if (e != null) {
                                  debugLog(
                                      getString(
                                              R.string
                                                  .com_parse_ui_login_warning_twitter_login_user_update_failed)
                                          + e.toString());
                                }
                                loginSuccess();
                              }
                            });
                      }
                    } else {
                      loginSuccess();
                    }
                  }
                });
          }
        });
  }
  private void setUpFacebookLogin() {
    facebookLoginButton.setVisibility(View.VISIBLE);

    if (config.getFacebookLoginButtonText() != null) {
      facebookLoginButton.setText(config.getFacebookLoginButtonText());
    }

    facebookLoginButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            loadingStart(true);
            ParseFacebookUtils.logIn(
                config.getFacebookLoginPermissions(),
                getActivity(),
                new LogInCallback() {
                  @Override
                  public void done(ParseUser user, ParseException e) {
                    if (isActivityDestroyed()) {
                      return;
                    }

                    if (user == null) {
                      loadingFinish();
                      if (e != null) {
                        showToast(R.string.com_parse_ui_facebook_login_failed_toast);
                        debugLog(
                            getString(R.string.com_parse_ui_login_warning_facebook_login_failed)
                                + e.toString());
                      }
                    } else if (user.isNew()) {
                      Request.newMeRequest(
                              ParseFacebookUtils.getSession(),
                              new Request.GraphUserCallback() {
                                @Override
                                public void onCompleted(GraphUser fbUser, Response response) {
                                  /*
                                    If we were able to successfully retrieve the Facebook
                                    user's name, let's set it on the fullName field.
                                  */
                                  ParseUser parseUser = ParseUser.getCurrentUser();
                                  if (fbUser != null
                                      && parseUser != null
                                      && fbUser.getName().length() > 0) {
                                    parseUser.put(USER_OBJECT_NAME_FIELD, fbUser.getName());
                                    parseUser.saveInBackground(
                                        new SaveCallback() {
                                          @Override
                                          public void done(ParseException e) {
                                            if (e != null) {
                                              debugLog(
                                                  getString(
                                                          R.string
                                                              .com_parse_ui_login_warning_facebook_login_user_update_failed)
                                                      + e.toString());
                                            }
                                            loginSuccess();
                                          }
                                        });
                                  }
                                  loginSuccess();
                                }
                              })
                          .executeAsync();
                    } else {
                      loginSuccess();
                    }
                  }
                });
          }
        });
  }