public class SearchForm extends LinearLayout {
 
  @InjectView(R.id.account)
  private Spinner mAccountSpinner;
  private AccountAdapter mAccountAdapter;
 
  @InjectView(R.id.keyword)
  private EditText mKeywordField;
 
  @InjectView(R.id.min_amount)
  private CurrencyEditText mMinAmountField;
 
  @InjectView(R.id.max_amount)
  private CurrencyEditText mMaxAmountField;
 
  public SearchFormModel(Context context, AttributeSet attrs) {
    super(context, attrs);
    setup(context);
  }
 
  private void setup(Context context) {
    LayoutInflater.from(context).inflate(R.layout.search_form, this, true);
 
    ButterKnife.inject(this); 
 
    mAccountAdapter = new AccountAdapter(context);
    mAccountSpinner.setAdapter(mAccountAdapter);
  }
 
  public initialize(List<Account> accounts) {
    mAccountAdapter.setItems(accounts);
  }
 
  public String getKeywords() {
    return mKeywordField.getText().toString();
  }
 
  public void setKeywords(String keywords) {
    mKeywordField.setText(keywords);
  }
 
  public MoneyAmount getMinimumAmount() {
    return mMinAmountField.getAmount();
  }
 
  public void setMinimumAmount(double amount) {
    mMinmountField.setAmountFromDouble(amount);
  }
 
  public MoneyAmount getMaximumAmount() {
    return mMaxAmountField.getAmount();
  }
 
  public void setMaximumAmount(double amount) {
    mMaxAmountField.setAmountFromDouble(amount);
  }
 
  public Account getSelectedAccount() {
    return mAccountSpinner.getSelectedItem();
  }  
 
  public boolean validate() {
    clearErrors();
    boolean isValid = true;
 
    if (!isValidAmountRange()) {
      isValid = false;
      mMinAmountField.setError("Invalid range");
      mMaxAmountField.setError("Invalid range");
    }
 
    return isValid;
  }
 
  private boolean isValidAmountRange() {
    return getMinimumAmount() <= getMaximumAmount();
  }
 
  private void clearErrors() {
    mMinAmountField.setError(null);
    mMaxAmountField.setError(null);
  }
 
  public SearchParameters buildParameters() {
    return new SearchParameters(getSelectedAccount(),
                                getKeywords(),
                                getMinimumAmount(),
                                getMaximumAmount());
  }
 
  public void persist(Bundle outState) {
    outState.putInt("SELECTED_ACCT_INDEX", mAccountSpinner.getSelectedItemPosition());
  }
 
  public void restore(Bundle bundle) {
    int accountPosition = bundle.getInt("SELECTED_ACCT_INDEX");
    mAccountSpinner.setSelection(accountPosition, false);
  }
}