/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */

#ifndef mozilla_dom_ContactsBinding_h
#define mozilla_dom_ContactsBinding_h

#include "ContactsBinding.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
#include "jspubtd.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CallbackInterface.h"
#include "mozilla/dom/Date.h"
#include "mozilla/dom/Nullable.h"
#include "nsIDOMFile.h"
#include "nsWeakReference.h"

class JSObject;
class nsIDOMBlob;

namespace mozilla {
namespace dom {

struct ContactAddress;
struct ContactAddressAtoms;
struct ContactField;
struct ContactFieldAtoms;
struct ContactFindOptions;
struct ContactFindOptionsAtoms;
struct ContactFindSortOptions;
struct ContactFindSortOptionsAtoms;
class ContactManager;
struct ContactManagerAtoms;
struct ContactProperties;
struct ContactPropertiesAtoms;
struct ContactTelField;
struct ContactTelFieldAtoms;
class DOMCursor;
class DOMRequest;
class EventHandlerNonNull;
class NativePropertyHooks;
class OwningmozContactOrString;
class ProtoAndIfaceCache;
class mozContact;
struct mozContactAtoms;
class mozContactOrString;

} // namespace dom
} // namespace mozilla

namespace mozilla {
namespace dom {

struct ContactAddress : public DictionaryBase
{
  Optional<nsString> mCountryName;
  Optional<nsString> mLocality;
  Optional<nsString> mPostalCode;
  Optional<Nullable<bool>> mPref;
  Optional<nsString> mRegion;
  Optional<nsString> mStreetAddress;
  Optional<Nullable<Sequence<nsString>>> mType;

  ContactAddress();

  explicit inline ContactAddress(const ContactAddress& aOther)
  {
    *this = aOther;
  }

protected:
  explicit inline ContactAddress(int )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  static bool
  InitIds(JSContext* cx, ContactAddressAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const ContactAddress& aOther);
};

namespace binding_detail {
struct FastContactAddress : public ContactAddress
{
  inline FastContactAddress()
    : ContactAddress(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct ContactField : public DictionaryBase
{
  Optional<Nullable<bool>> mPref;
  Optional<Nullable<Sequence<nsString>>> mType;
  Optional<nsString> mValue;

  ContactField();

  explicit inline ContactField(const ContactField& aOther)
  {
    *this = aOther;
  }

protected:
  explicit inline ContactField(int )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  static bool
  InitIds(JSContext* cx, ContactFieldAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const ContactField& aOther);
};

namespace binding_detail {
struct FastContactField : public ContactField
{
  inline FastContactField()
    : ContactField(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct ContactFindSortOptions : public DictionaryBase
{
  Optional<nsString> mSortBy;
  nsString mSortOrder;

  ContactFindSortOptions();

  explicit inline ContactFindSortOptions(const ContactFindSortOptions& aOther)
  {
    *this = aOther;
  }

protected:
  explicit inline ContactFindSortOptions(int )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  static bool
  InitIds(JSContext* cx, ContactFindSortOptionsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const ContactFindSortOptions& aOther);
};

namespace binding_detail {
struct FastContactFindSortOptions : public ContactFindSortOptions
{
  inline FastContactFindSortOptions()
    : ContactFindSortOptions(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct ContactFindOptions : public ContactFindSortOptions
{
  JS::Value mFilterBy;
  uint32_t mFilterLimit;
  Optional<nsString> mFilterOp;
  Optional<nsString> mFilterValue;

  ContactFindOptions();

protected:
  explicit inline ContactFindOptions(int )
    : mFilterBy(JS::UndefinedValue())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  ContactFindOptions(const ContactFindOptions&) MOZ_DELETE;
  void operator=(const ContactFindOptions) MOZ_DELETE;

  static bool
  InitIds(JSContext* cx, ContactFindOptionsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastContactFindOptions : public ContactFindOptions
{
  inline FastContactFindOptions()
    : ContactFindOptions(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct ContactTelField : public ContactField
{
  Optional<nsString> mCarrier;

  ContactTelField();

  explicit inline ContactTelField(const ContactTelField& aOther)
  {
    *this = aOther;
  }

protected:
  explicit inline ContactTelField(int )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  static bool
  InitIds(JSContext* cx, ContactTelFieldAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const ContactTelField& aOther);
};

namespace binding_detail {
struct FastContactTelField : public ContactTelField
{
  inline FastContactTelField()
    : ContactTelField(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct ContactProperties : public DictionaryBase
{
  Optional<Nullable<Sequence<nsString>>> mAdditionalName;
  Optional<Nullable<Sequence<ContactAddress>>> mAdr;
  Optional<Nullable<Date>> mAnniversary;
  Optional<Nullable<Date>> mBday;
  Optional<Nullable<Sequence<nsString>>> mCategory;
  Optional<Nullable<Sequence<ContactField>>> mEmail;
  Optional<Nullable<Sequence<nsString>>> mFamilyName;
  Optional<nsString> mGenderIdentity;
  Optional<Nullable<Sequence<nsString>>> mGivenName;
  Optional<Nullable<Sequence<nsString>>> mHonorificPrefix;
  Optional<Nullable<Sequence<nsString>>> mHonorificSuffix;
  Optional<Nullable<Sequence<ContactField>>> mImpp;
  Optional<Nullable<Sequence<nsString>>> mJobTitle;
  Optional<Nullable<Sequence<nsString>>> mKey;
  Optional<Nullable<Sequence<nsString>>> mName;
  Optional<Nullable<Sequence<nsString>>> mNickname;
  Optional<Nullable<Sequence<nsString>>> mNote;
  Optional<Nullable<Sequence<nsString>>> mOrg;
  Optional<Nullable<Sequence<nsString>>> mPhoneticFamilyName;
  Optional<Nullable<Sequence<nsString>>> mPhoneticGivenName;
  Optional<Nullable<Sequence<nsRefPtr<nsIDOMBlob>>>> mPhoto;
  Optional<nsString> mSex;
  Optional<Nullable<Sequence<ContactTelField>>> mTel;
  Optional<Nullable<Sequence<ContactField>>> mUrl;

  ContactProperties();

protected:
  explicit inline ContactProperties(int )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  ContactProperties(const ContactProperties&) MOZ_DELETE;
  void operator=(const ContactProperties) MOZ_DELETE;

  static bool
  InitIds(JSContext* cx, ContactPropertiesAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value");

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastContactProperties : public ContactProperties
{
  inline FastContactProperties()
    : ContactProperties(42)
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


namespace ContactManagerBinding {

  typedef mozilla::dom::ContactManager NativeType;

  JSObject*
  ConstructNavigatorObject(JSContext* aCx, JS::Handle<JSObject*> aObj);

  // We declare this as an array so that retrieving a pointer to this
  // binding's property hooks only requires compile/link-time resolvable
  // address arithmetic.  Declaring it as a pointer instead would require
  // doing a run-time load to fetch a pointer to this binding's property
  // hooks.  And then structures which embedded a pointer to this structure
  // would require a run-time load for proper initialization, which would
  // then induce static constructors.  Lots of static constructors.
  extern const NativePropertyHooks sNativePropertyHooks[];

  const JSClass*
  GetJSClass();

  JSObject*
  Wrap(JSContext* aCx, mozilla::dom::ContactManager* aObject, nsWrapperCache* aCache);

  template <class T>
  inline JSObject* Wrap(JSContext* aCx, T* aObject)
  {
    return Wrap(aCx, aObject, aObject);
  }

  void
  CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal);

  JS::Handle<JSObject*>
  GetProtoObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal);

} // namespace ContactManagerBinding



namespace mozContactBinding {

  typedef mozilla::dom::mozContact NativeType;

  // We declare this as an array so that retrieving a pointer to this
  // binding's property hooks only requires compile/link-time resolvable
  // address arithmetic.  Declaring it as a pointer instead would require
  // doing a run-time load to fetch a pointer to this binding's property
  // hooks.  And then structures which embedded a pointer to this structure
  // would require a run-time load for proper initialization, which would
  // then induce static constructors.  Lots of static constructors.
  extern const NativePropertyHooks sNativePropertyHooks[];

  JSObject*
  DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal);

  const JSClass*
  GetJSClass();

  JSObject*
  Wrap(JSContext* aCx, mozilla::dom::mozContact* aObject, nsWrapperCache* aCache);

  template <class T>
  inline JSObject* Wrap(JSContext* aCx, T* aObject)
  {
    return Wrap(aCx, aObject, aObject);
  }

  void
  ClearCachedPhotoValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedAdrValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedEmailValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedUrlValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedImppValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedTelValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedHonorificPrefixValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedGivenNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedPhoneticGivenNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedAdditionalNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedFamilyNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedPhoneticFamilyNameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedHonorificSuffixValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedNicknameValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedCategoryValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedOrgValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedJobTitleValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedNoteValue(mozilla::dom::mozContact* aObject);

  void
  ClearCachedKeyValue(mozilla::dom::mozContact* aObject);

  void
  CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal);

  JS::Handle<JSObject*>
  GetProtoObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal);

  JS::Handle<JSObject*>
  GetConstructorObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal, bool aDefineOnGlobal = true);

} // namespace mozContactBinding



class ContactManagerJSImpl : public CallbackInterface
{
public:
  explicit inline ContactManagerJSImpl(JS::Handle<JSObject*> aCallback, nsIGlobalObject* aIncumbentGlobal)
    : CallbackInterface(aCallback, aIncumbentGlobal)
  {
  }

  already_AddRefed<DOMRequest> Find(const ContactFindOptions& options, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMCursor> GetAll(const ContactFindSortOptions& options, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMRequest> Clear(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMRequest> Save(mozContact& contact, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMRequest> Remove(const mozContactOrString& contactOrId, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMRequest> GetRevision(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<DOMRequest> GetCount(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  inline bool
  operator==(const ContactManagerJSImpl& aOther) const
  {
    return CallbackInterface::operator==(aOther);
  }

  already_AddRefed<EventHandlerNonNull> GetOncontactchange(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetOncontactchange(EventHandlerNonNull* arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

private:
  static bool
  InitIds(JSContext* cx, ContactManagerAtoms* atomsCache);
};


class ContactManager MOZ_FINAL : public mozilla::DOMEventTargetHelper
{
public:
  NS_DECL_ISUPPORTS_INHERITED
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ContactManager, mozilla::DOMEventTargetHelper)

private:
  nsRefPtr<ContactManagerJSImpl> mImpl;
  nsCOMPtr<nsISupports> mParent;

public:
  ContactManager(JS::Handle<JSObject*> aJSImplObject, nsPIDOMWindow* aParent);

  nsISupports* GetParentObject() const;

  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> Find(const ContactFindOptions& options, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMCursor> GetAll(const ContactFindSortOptions& options, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> Clear(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> Save(mozContact& contact, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> Remove(const mozContactOrString& contactOrId, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> GetRevision(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  // Mark this as resultNotAddRefed to return raw pointers
  already_AddRefed<DOMRequest> GetCount(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  already_AddRefed<EventHandlerNonNull> GetOncontactchange(ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetOncontactchange(EventHandlerNonNull* arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  static bool
  _Create(JSContext* cx, unsigned argc, JS::Value* vp);
};


class mozContactJSImpl : public CallbackInterface
{
public:
  explicit inline mozContactJSImpl(JS::Handle<JSObject*> aCallback, nsIGlobalObject* aIncumbentGlobal)
    : CallbackInterface(aCallback, aIncumbentGlobal)
  {
  }

  void Init(const ContactProperties& properties, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetMetadata(const nsAString& id, const Nullable<Date>& published, const Nullable<Date>& updated, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void __Init(const ContactProperties& properties, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  inline bool
  operator==(const mozContactJSImpl& aOther) const
  {
    return CallbackInterface::operator==(aOther);
  }

  void GetId(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetPublished(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetUpdated(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetBday(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetAnniversary(ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetSex(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetGenderIdentity(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoto(Nullable<nsTArray<nsRefPtr<nsIDOMBlob>>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetAdr(Nullable<nsTArray<ContactAddress>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetEmail(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetUrl(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetImpp(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetTel(Nullable<nsTArray<ContactTelField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetHonorificPrefix(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetGivenName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoneticGivenName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetAdditionalName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetFamilyName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoneticFamilyName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetHonorificSuffix(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetNickname(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetCategory(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetOrg(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetJobTitle(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetNote(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetKey(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetId(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetBday(const Nullable<Date>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetAnniversary(const Nullable<Date>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetSex(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetGenderIdentity(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetPhoto(const Nullable<Sequence<nsRefPtr<nsIDOMBlob>>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetAdr(const Nullable<Sequence<ContactAddress>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetEmail(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetUrl(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetImpp(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetTel(const Nullable<Sequence<ContactTelField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetHonorificPrefix(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetGivenName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetPhoneticGivenName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetAdditionalName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetFamilyName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetPhoneticFamilyName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetHonorificSuffix(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetNickname(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetCategory(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetOrg(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetJobTitle(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetNote(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetKey(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

private:
  static bool
  InitIds(JSContext* cx, mozContactAtoms* atomsCache);
};


class mozContact MOZ_FINAL : public nsSupportsWeakReference,
                             public nsWrapperCache
{
public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(mozContact)

private:
  nsRefPtr<mozContactJSImpl> mImpl;
  nsCOMPtr<nsISupports> mParent;

public:
  mozContact(JS::Handle<JSObject*> aJSImplObject, nsPIDOMWindow* aParent);

  nsISupports* GetParentObject() const;

  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;

  static already_AddRefed<mozContact> Constructor(const GlobalObject& global, JSContext* cx, const ContactProperties& properties, ErrorResult& aRv);

  void GetId(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetId(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetPublished(ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  Nullable<Date> GetUpdated(ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  Nullable<Date> GetBday(ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetBday(const Nullable<Date>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  Nullable<Date> GetAnniversary(ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetAnniversary(const Nullable<Date>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetSex(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetSex(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetGenderIdentity(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetGenderIdentity(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoto(Nullable<nsTArray<// Mark this as resultNotAddRefed to return raw pointers
  nsRefPtr<nsIDOMBlob>>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetPhoto(const Nullable<Sequence<nsRefPtr<nsIDOMBlob>>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetAdr(Nullable<nsTArray<ContactAddress>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetAdr(const Nullable<Sequence<ContactAddress>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetEmail(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetEmail(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetUrl(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetUrl(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetImpp(Nullable<nsTArray<ContactField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetImpp(const Nullable<Sequence<ContactField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetTel(Nullable<nsTArray<ContactTelField>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetTel(const Nullable<Sequence<ContactTelField>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetHonorificPrefix(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetHonorificPrefix(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetGivenName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetGivenName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoneticGivenName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetPhoneticGivenName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetAdditionalName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetAdditionalName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetFamilyName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetFamilyName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetPhoneticFamilyName(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetPhoneticFamilyName(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetHonorificSuffix(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetHonorificSuffix(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetNickname(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetNickname(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetCategory(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetCategory(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetOrg(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetOrg(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetJobTitle(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetJobTitle(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetNote(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetNote(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void GetKey(Nullable<nsTArray<nsString>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment = nullptr) const;

  void SetKey(const Nullable<Sequence<nsString>>& arg, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void Init(const ContactProperties& properties, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  void SetMetadata(const nsAString& id, const Nullable<Date>& published, const Nullable<Date>& updated, ErrorResult& aRv, JSCompartment* aCompartment = nullptr);

  static bool
  _Create(JSContext* cx, unsigned argc, JS::Value* vp);
};


} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_ContactsBinding_h
