    001    package com.skype.api;
    002
    003    import com.skype.ipc.SidRoot;
    004    import com.skype.ipc.SidObject;
    005    import com.skype.ipc.EnumConverting;
    006    import com.skype.ipc.PropertyEnumConverting;
    007    import com.skype.ipc.Decoding;
    008    import com.skype.ipc.Encoding;
    009    import com.skype.ipc.Encoding;
    010    import java.io.IOException;
    011    import com.skype.ipc.PropertyEnumConverting;
    012    import com.skype.api.ContactGroup;
    013    import com.skype.ipc.SidGetResponding;
    014
    015    /** Address book entry. Encapsulates methods like GetIdentity, GetAvatar, SendAuthRequest, OpenConversation etc. Single contact can have additional phone numbers attached to it (ASSIGNED_PHONE1 .. ASSIGNED_PHONE3). Note that in the context of a conversation, Contacts are represented by Participant objects. Contact member functions all return a Boolean indicating the success (true) or failure (false) of processing the request itself (transport, runtime availability, and so forth)?not the success or failure of its associated functionality. For example, Contact.IsMemberOf returns true if it was able to make a determination, and its result parameter reflects whether this Contact is a member of the target group. Similarly, Contact.IsMemberOf returns false if it was unable to make a determination, and the value of its result parameter is undefined.  */
    016    public final class Contact extends SidObject {
    017            /** Same as with CAPABILITY, enumerator is used by both Contact and Account objects.  */
    018            public enum Type implements EnumConverting {
    019                    /** Contact/account has no pre-identified type. This type is reported by default for SkypeKit clients.  */
    020                    UNRECOGNIZED    (0),
    021                    /** Normal Skype contact.  */
    022                    SKYPE           (1),
    023                    /** Normal PSTN contact.  */
    024                    PSTN            (2),
    025                    /** Emergency number (i.e. 911).  */
    026                    EMERGENCY_PSTN  (3),
    027                    FREE_PSTN       (4),
    028                    /** Undisclosed PSTN number.  */
    029                    UNDISCLOSED_PSTN(5),
    030                    /** This type is currently used by Windows desktop clients for contacts imported from Outlook.  */
    031                    EXTERNAL        (6);
    032                    private final int key;
    033                    Type(int key) {
    034                            this.key = key;
    035                    };
    036                    public int getId()   { return key; }
    037                    public EnumConverting getDefault() { return UNRECOGNIZED; }
    038                    public EnumConverting convert(int from) { return Type.get(from); }
    039                    public EnumConverting[] getArray(final int size) { return new Type[size]; }
    040                    public static Type get(int from) {
    041                            switch (from) {
    042                            case 0: return UNRECOGNIZED;
    043                            case 1: return SKYPE;
    044                            case 2: return PSTN;
    045                            case 3: return EMERGENCY_PSTN;
    046                            case 4: return FREE_PSTN;
    047                            case 5: return UNDISCLOSED_PSTN;
    048                            case 6: return EXTERNAL;
    049                            }
    050                            return UNRECOGNIZED;
    051                    }
    052                    public static final int UNRECOGNIZED_VALUE     = 0;
    053                    public static final int SKYPE_VALUE            = 1;
    054                    public static final int PSTN_VALUE             = 2;
    055                    public static final int EMERGENCY_PSTN_VALUE   = 3;
    056                    public static final int FREE_PSTN_VALUE        = 4;
    057                    public static final int UNDISCLOSED_PSTN_VALUE = 5;
    058                    public static final int EXTERNAL_VALUE         = 6;
    059            }
    060            /** Describes the recognized relational states between a local account and a remote contact.  */
    061            public enum AuthLevel implements EnumConverting {
    062                    /** Authorization request is either ignored or pending. In this state several functionalities may be blocked, depending on settings. For example, accounts may only allow seeing online presence to be viewable or only receive calls from authorized contacts.  */
    063                    NONE            (0),
    064                    /** Contact has been authorized by the local account.  */
    065                    AUTHORIZED_BY_ME(1),
    066                    /** Contact has been blocked by the local account. This prevents incoming calls, chat messages, additional authorization requests etc.  */
    067                    BLOCKED_BY_ME   (2);
    068                    private final int key;
    069                    AuthLevel(int key) {
    070                            this.key = key;
    071                    };
    072                    public int getId()   { return key; }
    073                    public EnumConverting getDefault() { return NONE; }
    074                    public EnumConverting convert(int from) { return AuthLevel.get(from); }
    075                    public EnumConverting[] getArray(final int size) { return new AuthLevel[size]; }
    076                    public static AuthLevel get(int from) {
    077                            switch (from) {
    078                            case 0: return NONE;
    079                            case 1: return AUTHORIZED_BY_ME;
    080                            case 2: return BLOCKED_BY_ME;
    081                            }
    082                            return NONE;
    083                    }
    084                    public static final int NONE_VALUE             = 0;
    085                    public static final int AUTHORIZED_BY_ME_VALUE = 1;
    086                    public static final int BLOCKED_BY_ME_VALUE    = 2;
    087            }
    088            /** Describes the superset list of possible Account and Contact online statuses. In case of Account they apply to local user, in case of Contact they apply to remote contacts.  */
    089            public enum Availability implements EnumConverting {
    090                    /** Contact online status cannot be determined. This availability state should not normally reach the SkypeKit UI level.  */
    091                    UNKNOWN                   (0),
    092                    /** Seeing Contact online status is blocked because authorization between contact and local account has not taken place.  */
    093                    PENDINGAUTH               (8),
    094                    /** Remote contact has been blocked by local account. This applies to online accounts.  */
    095                    BLOCKED                   (9),
    096                    /** Remote SkypeOut contact has been blocked by local account.  */
    097                    BLOCKED_SKYPEOUT          (11),
    098                    /** Contact does not have an online status because he is a PSTN contact.  */
    099                    SKYPEOUT                  (10),
    100                    /** Contact appears to be offline.  */
    101                    OFFLINE                   (1),
    102                    /** Contact appears to be offline but has voicemail enabled.  */
    103                    OFFLINE_BUT_VM_ABLE       (12),
    104                    /** Contact appears to be offline but has enabled call forwarding, so calls may actually get through to him.  */
    105                    OFFLINE_BUT_CF_ABLE       (13),
    106                    /** Contact / Account is online  */
    107                    ONLINE                    (2),
    108                    /** Contact / Account is online but away from keyboard. This can be either turned on manually or by automatic timer. In Windows desktop client, the timer can be configured with minute precision.  */
    109                    AWAY                      (3),
    110                    /** This online status is marked as deprecated. If a remote contact indicates its status as NOT_AVAILABLE, the UI should handle this as equivalent of AWAY status.  */
    111                    NOT_AVAILABLE             (4),
    112                    /** Contact / Account is online but does not wish to be disturbed. This status supersedes AWAY status when the account is DO_NOT_DISTURB the AWAY timer should not modify the status.  */
    113                    DO_NOT_DISTURB            (5),
    114                    /** This online status is marked as deprecated. If a remote contact indicates its status as SKYPE_ME, the UI should handle this as equivalent of ONLINE status.  */
    115                    SKYPE_ME                  (7),
    116                    /** Account status is set to INVISIBLE. This status in not applicable to remote Contacts. When the remote contact has set his availability to INVISIBLE, he will appear as OFFLINE to others.  */
    117                    INVISIBLE                 (6),
    118                    /** only possible for local user/account */
    119                    CONNECTING                (14),
    120                    ONLINE_FROM_MOBILE        (15),
    121                    /** *_FROM_MOBILE only possible for remote user */
    122                    AWAY_FROM_MOBILE          (16),
    123                    NOT_AVAILABLE_FROM_MOBILE (17),
    124                    DO_NOT_DISTURB_FROM_MOBILE(18),
    125                    SKYPE_ME_FROM_MOBILE      (20);
    126                    private final int key;
    127                    Availability(int key) {
    128                            this.key = key;
    129                    };
    130                    public int getId()   { return key; }
    131                    public EnumConverting getDefault() { return UNKNOWN; }
    132                    public EnumConverting convert(int from) { return Availability.get(from); }
    133                    public EnumConverting[] getArray(final int size) { return new Availability[size]; }
    134                    public static Availability get(int from) {
    135                            switch (from) {
    136                            case  0: return UNKNOWN;
    137                            case  8: return PENDINGAUTH;
    138                            case  9: return BLOCKED;
    139                            case 11: return BLOCKED_SKYPEOUT;
    140                            case 10: return SKYPEOUT;
    141                            case  1: return OFFLINE;
    142                            case 12: return OFFLINE_BUT_VM_ABLE;
    143                            case 13: return OFFLINE_BUT_CF_ABLE;
    144                            case  2: return ONLINE;
    145                            case  3: return AWAY;
    146                            case  4: return NOT_AVAILABLE;
    147                            case  5: return DO_NOT_DISTURB;
    148                            case  7: return SKYPE_ME;
    149                            case  6: return INVISIBLE;
    150                            case 14: return CONNECTING;
    151                            case 15: return ONLINE_FROM_MOBILE;
    152                            case 16: return AWAY_FROM_MOBILE;
    153                            case 17: return NOT_AVAILABLE_FROM_MOBILE;
    154                            case 18: return DO_NOT_DISTURB_FROM_MOBILE;
    155                            case 20: return SKYPE_ME_FROM_MOBILE;
    156                            }
    157                            return UNKNOWN;
    158                    }
    159                    public static final int UNKNOWN_VALUE                    =  0;
    160                    public static final int PENDINGAUTH_VALUE                =  8;
    161                    public static final int BLOCKED_VALUE                    =  9;
    162                    public static final int BLOCKED_SKYPEOUT_VALUE           = 11;
    163                    public static final int SKYPEOUT_VALUE                   = 10;
    164                    public static final int OFFLINE_VALUE                    =  1;
    165                    public static final int OFFLINE_BUT_VM_ABLE_VALUE        = 12;
    166                    public static final int OFFLINE_BUT_CF_ABLE_VALUE        = 13;          public static final int ONLINE_VALUE                     =  2;
    167                    public static final int AWAY_VALUE                       =  3;
    168                    public static final int NOT_AVAILABLE_VALUE              =  4;
    169                    public static final int DO_NOT_DISTURB_VALUE             =  5;
    170                    public static final int SKYPE_ME_VALUE                   =  7;
    171                    public static final int INVISIBLE_VALUE                  =  6;
    172                    public static final int CONNECTING_VALUE                 = 14;
    173                    public static final int ONLINE_FROM_MOBILE_VALUE         = 15;
    174                    public static final int AWAY_FROM_MOBILE_VALUE           = 16;
    175                    public static final int NOT_AVAILABLE_FROM_MOBILE_VALUE  = 17;
    176                    public static final int DO_NOT_DISTURB_FROM_MOBILE_VALUE = 18;
    177                    public static final int SKYPE_ME_FROM_MOBILE_VALUE       = 20;
    178            }
    179            public enum ExtraAuthReqFields implements EnumConverting {
    180                    /** send verified e-mail blob with this auth request */
    181                    SEND_VERIFIED_EMAIL  (1),
    182                    /** send verified company blob with this auth request */
    183                    SEND_VERIFIED_COMPANY(2);
    184                    private final int key;
    185                    ExtraAuthReqFields(int key) {
    186                            this.key = key;
    187                    };
    188                    public int getId()   { return key; }
    189                    public EnumConverting getDefault() { return SEND_VERIFIED_EMAIL; }
    190                    public EnumConverting convert(int from) { return ExtraAuthReqFields.get(from); }
    191                    public EnumConverting[] getArray(final int size) { return new ExtraAuthReqFields[size]; }
    192                    public static ExtraAuthReqFields get(int from) {
    193                            switch (from) {
    194                            case 1: return SEND_VERIFIED_EMAIL;
    195                            case 2: return SEND_VERIFIED_COMPANY;
    196                            }
    197                            return SEND_VERIFIED_EMAIL;
    198                    }
    199                    public static final int SEND_VERIFIED_EMAIL_VALUE   = 1;
    200                    public static final int SEND_VERIFIED_COMPANY_VALUE = 2;
    201            }
    202            /**
    203             * This enumerator is used by both Contact and Account objects. Thus the items here can have slightly different meaning, depending on which context you will examine their values. In case of Contact, the values apply to a user - across all the instances that user has logged in with Skype. In case of Account, the capability is that of a local, currently logged in instance of Skype client.
    204             *
    205             * The values that CAPABILITY items can have are also dependant on class context. In context of Contact, a capability can be CAPABILITY_MIXED. Which in case of CAPABILITY_VIDEO, for example, would mean that the remote use has logged in with different clients, some of which support video calls and some of which don't. In context of Account - there are no mixed result. Currently logged in Skype instance either supports video or it doesn't.
    206             */
    207            public enum Capability implements EnumConverting {
    208                    /** For Account object, this is the same as CAPABILITY_CAN_BE_SENT_VM - it indicates that the currently logged in Skype instance supports voicemails. For Contact objects, it means that their remote system supports sending voicemails - there is no technical method for Skype to detect whether they are capable of receiving voicemails, so the assumption is that they can.  */
    209                    CAPABILITY_VOICEMAIL         (0),
    210                    /** Indicates that the contact/account has SkypeOut and is thus capable of making PSTN calls.  */
    211                    CAPABILITY_SKYPEOUT          (1),
    212                    /** Indicates that the contact/account has SkypeIn and is thus capable of answering PSTN calls.  */
    213                    CAPABILITY_SKYPEIN           (2),
    214                    /** For contacts, this is a combination of CAPABILITY_VOICEMAIL for local account (local Skype client supports sending voicemails) and CAPABILITY_VOICEMAIL of the Contact - if the contact supports sending voicemails then hopefully they can also receive them.  */
    215                    CAPABILITY_CAN_BE_SENT_VM    (3),
    216                    /** Indicates that Account/Contact supports call forwarding.  */
    217                    CAPABILITY_CALL_FORWARD      (4),
    218                    /** Indicates that Account/Contact supports call video calls.  */
    219                    CAPABILITY_VIDEO             (5),
    220                    /** In context of Contact, this indicates that the user is noticed running at least one Skype implementation that supports text messaging. Basically, it applies to a user. When applied to Account, the meaning is slightly different. In that case it indicates that currently running Skype implementation supports chat messaging. So, for Account objects, this is a node (rather than user) capability.  */
    221                    CAPABILITY_TEXT              (6),
    222                    /** Indicates that the contact/account is flagged as SkypePrime service provider. This is linked to Account class SERVICE_PROVIDER_INFO property.  */
    223                    CAPABILITY_SERVICE_PROVIDER  (7),
    224                    /** This is a legacy item, from the old times when conference calls with more than 5 people were limited to SkypePro accounts. In other words, this item is no longer relevant and will likely be removed at some point in future.  */
    225                    CAPABILITY_LARGE_CONFERENCE  (8),
    226                    CAPABILITY_COMMERCIAL_CONTACT(9),
    227                    /** Indicates that Account/Contact supports call transfers to PSTN numbers.  */
    228                    CAPABILITY_PSTN_TRANSFER     (10),
    229                    /** Indicates that the user has had his chat capability removed by Skype. Basically, this means that the user is reported as spammer too many times. This applies for both Contact and Account objects - which means your client can check locally, if the currently logged in user has been marked as a spammer.  */
    230                    CAPABILITY_TEXT_EVER         (11),
    231                    /** Indicates that the user (Account or Contact) has had his voice call capability removed by Skype.  */
    232                    CAPABILITY_VOICE_EVER        (12),
    233                    /** Indicates that the instance of Skype client Account/Contact is or in Contact's case has at least occasionally been flagged as a mobile device.  */
    234                    CAPABILITY_MOBILE_DEVICE     (13),
    235                    CAPABILITY_PUBLIC_CONTACT    (14);
    236                    private final int key;
    237                    Capability(int key) {
    238                            this.key = key;
    239                    };
    240                    public int getId()   { return key; }
    241                    public EnumConverting getDefault() { return CAPABILITY_VOICEMAIL; }
    242                    public EnumConverting convert(int from) { return Capability.get(from); }
    243                    public EnumConverting[] getArray(final int size) { return new Capability[size]; }
    244                    public static Capability get(int from) {
    245                            switch (from) {
    246                            case  0: return CAPABILITY_VOICEMAIL;
    247                            case  1: return CAPABILITY_SKYPEOUT;
    248                            case  2: return CAPABILITY_SKYPEIN;
    249                            case  3: return CAPABILITY_CAN_BE_SENT_VM;
    250                            case  4: return CAPABILITY_CALL_FORWARD;
    251                            case  5: return CAPABILITY_VIDEO;
    252                            case  6: return CAPABILITY_TEXT;
    253                            case  7: return CAPABILITY_SERVICE_PROVIDER;
    254                            case  8: return CAPABILITY_LARGE_CONFERENCE;
    255                            case  9: return CAPABILITY_COMMERCIAL_CONTACT;
    256                            case 10: return CAPABILITY_PSTN_TRANSFER;
    257                            case 11: return CAPABILITY_TEXT_EVER;
    258                            case 12: return CAPABILITY_VOICE_EVER;
    259                            case 13: return CAPABILITY_MOBILE_DEVICE;
    260                            case 14: return CAPABILITY_PUBLIC_CONTACT;
    261                            }
    262                            return CAPABILITY_VOICEMAIL;
    263                    }
    264                    public static final int CAPABILITY_VOICEMAIL_VALUE          =  0;
    265                    public static final int CAPABILITY_SKYPEOUT_VALUE           =  1;
    266                    public static final int CAPABILITY_SKYPEIN_VALUE            =  2;
    267                    public static final int CAPABILITY_CAN_BE_SENT_VM_VALUE     =  3;
    268                    public static final int CAPABILITY_CALL_FORWARD_VALUE       =  4;
    269                    public static final int CAPABILITY_VIDEO_VALUE              =  5;
    270                    public static final int CAPABILITY_TEXT_VALUE               =  6;
    271                    public static final int CAPABILITY_SERVICE_PROVIDER_VALUE   =  7;
    272                    public static final int CAPABILITY_LARGE_CONFERENCE_VALUE   =  8;
    273                    public static final int CAPABILITY_COMMERCIAL_CONTACT_VALUE =  9;
    274                    public static final int CAPABILITY_PSTN_TRANSFER_VALUE      = 10;
    275                    public static final int CAPABILITY_TEXT_EVER_VALUE          = 11;
    276                    public static final int CAPABILITY_VOICE_EVER_VALUE         = 12;
    277                    public static final int CAPABILITY_MOBILE_DEVICE_VALUE      = 13;
    278                    public static final int CAPABILITY_PUBLIC_CONTACT_VALUE     = 14;
    279            }
    280            /** List of possible states of each of the Contact class CAPABILITY items.  */
    281            public enum Capabilitystatus implements EnumConverting {
    282                    /** Contact does not have the capability  */
    283                    NO_CAPABILITY    (0),
    284                    /** Contact has occasionally logged in with Skype client that supports the capability. For example, a contact may have Skype client on several machines, only some of which have webcam - in which case CAPABILITY_VIDEO would have its value set as CAPABILITY_MIXED.  */
    285                    CAPABILITY_MIXED (1),
    286                    /** Contact has the capability  */              CAPABILITY_EXISTS(2);
    287                    private final int key;
    288                    Capabilitystatus(int key) {
    289                            this.key = key;
    290                    };
    291                    public int getId()   { return key; }
    292                    public EnumConverting getDefault() { return NO_CAPABILITY; }
    293                    public EnumConverting convert(int from) { return Capabilitystatus.get(from); }
    294                    public EnumConverting[] getArray(final int size) { return new Capabilitystatus[size]; }
    295                    public static Capabilitystatus get(int from) {
    296                            switch (from) {
    297                            case 0: return NO_CAPABILITY;
    298                            case 1: return CAPABILITY_MIXED;
    299                            case 2: return CAPABILITY_EXISTS;
    300                            }
    301                            return NO_CAPABILITY;
    302                    }
    303                    public static final int NO_CAPABILITY_VALUE     = 0;
    304                    public static final int CAPABILITY_MIXED_VALUE  = 1;
    305                    public static final int CAPABILITY_EXISTS_VALUE = 2;
    306            }
    307            private final static byte[] P_TYPE_req = {(byte) 90,(byte) 71,(byte) 202,(byte) 1,(byte) 93,(byte) 2};
    308            private final static byte[] P_SKYPE_NAME_req = {(byte) 90,(byte) 71,(byte) 4,(byte) 93,(byte) 2};
    309            private final static byte[] P_PSTN_NUMBER_req = {(byte) 90,(byte) 71,(byte) 6,(byte) 93,(byte) 2};
    310            private final static byte[] P_FULL_NAME_req = {(byte) 90,(byte) 71,(byte) 5,(byte) 93,(byte) 2};
    311            private final static byte[] P_BIRTHDAY_req = {(byte) 90,(byte) 71,(byte) 7,(byte) 93,(byte) 2};
    312            private final static byte[] P_GENDER_req = {(byte) 90,(byte) 71,(byte) 8,(byte) 93,(byte) 2};
    313            private final static byte[] P_LANGUAGES_req = {(byte) 90,(byte) 71,(byte) 9,(byte) 93,(byte) 2};
    314            private final static byte[] P_COUNTRY_req = {(byte) 90,(byte) 71,(byte) 10,(byte) 93,(byte) 2};
    315            private final static byte[] P_PROVINCE_req = {(byte) 90,(byte) 71,(byte) 11,(byte) 93,(byte) 2};
    316            private final static byte[] P_CITY_req = {(byte) 90,(byte) 71,(byte) 12,(byte) 93,(byte) 2};
    317            private final static byte[] P_PHONE_HOME_req = {(byte) 90,(byte) 71,(byte) 13,(byte) 93,(byte) 2};
    318            private final static byte[] P_PHONE_OFFICE_req = {(byte) 90,(byte) 71,(byte) 14,(byte) 93,(byte) 2};
    319            private final static byte[] P_PHONE_MOBILE_req = {(byte) 90,(byte) 71,(byte) 15,(byte) 93,(byte) 2};
    320            private final static byte[] P_EMAILS_req = {(byte) 90,(byte) 71,(byte) 16,(byte) 93,(byte) 2};
    321            private final static byte[] P_HOMEPAGE_req = {(byte) 90,(byte) 71,(byte) 17,(byte) 93,(byte) 2};
    322            private final static byte[] P_ABOUT_req = {(byte) 90,(byte) 71,(byte) 18,(byte) 93,(byte) 2};
    323            private final static byte[] P_AVATAR_IMAGE_req = {(byte) 90,(byte) 71,(byte) 37,(byte) 93,(byte) 2};
    324            private final static byte[] P_MOOD_TEXT_req = {(byte) 90,(byte) 71,(byte) 26,(byte) 93,(byte) 2};
    325            private final static byte[] P_RICH_MOOD_TEXT_req = {(byte) 90,(byte) 71,(byte) 205,(byte) 1,(byte) 93,(byte) 2};
    326            private final static byte[] P_TIMEZONE_req = {(byte) 90,(byte) 71,(byte) 27,(byte) 93,(byte) 2};
    327            private final static byte[] P_CAPABILITIES_req = {(byte) 90,(byte) 71,(byte) 36,(byte) 93,(byte) 2};
    328            private final static byte[] P_PROFILE_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 19,(byte) 93,(byte) 2};
    329            private final static byte[] P_NROF_AUTHED_BUDDIES_req = {(byte) 90,(byte) 71,(byte) 28,(byte) 93,(byte) 2};
    330            private final static byte[] P_IP_COUNTRY_req = {(byte) 90,(byte) 71,(byte) 29,(byte) 93,(byte) 2};
    331            private final static byte[] P_AVATAR_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 182,(byte) 1,(byte) 93,(byte) 2};
    332            private final static byte[] P_MOOD_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 183,(byte) 1,(byte) 93,(byte) 2};
    333            private final static byte[] P_RECEIVED_AUTH_REQUEST_req = {(byte) 90,(byte) 71,(byte) 20,(byte) 93,(byte) 2};
    334            private final static byte[] P_AUTH_REQUEST_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 25,(byte) 93,(byte) 2};
    335            private final static byte[] P_LAST_ONLINE_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 35,(byte) 93,(byte) 2};
    336            private final static byte[] P_AVAILABILITY_req = {(byte) 90,(byte) 71,(byte) 34,(byte) 93,(byte) 2};
    337            private final static byte[] P_DISPLAY_NAME_req = {(byte) 90,(byte) 71,(byte) 21,(byte) 93,(byte) 2};
    338            private final static byte[] P_REFRESHING_req = {(byte) 90,(byte) 71,(byte) 22,(byte) 93,(byte) 2};
    339            private final static byte[] P_GIVEN_AUTH_LEVEL_req = {(byte) 90,(byte) 71,(byte) 23,(byte) 93,(byte) 2};
    340            private final static byte[] P_GIVEN_DISPLAY_NAME_req = {(byte) 90,(byte) 71,(byte) 33,(byte) 93,(byte) 2};
    341            private final static byte[] P_ASSIGNED_COMMENT_req = {(byte) 90,(byte) 71,(byte) 180,(byte) 1,(byte) 93,(byte) 2};
    342            private final static byte[] P_LAST_USED_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 39,(byte) 93,(byte) 2};
    343            private final static byte[] P_AUTH_REQUEST_COUNT_req = {(byte) 90,(byte) 71,(byte) 41,(byte) 93,(byte) 2};
    344            private final static byte[] P_ASSIGNED_PHONE1_req = {(byte) 90,(byte) 71,(byte) 184,(byte) 1,(byte) 93,(byte) 2};
    345            private final static byte[] P_ASSIGNED_PHONE1_LABEL_req = {(byte) 90,(byte) 71,(byte) 185,(byte) 1,(byte) 93,(byte) 2};
    346            private final static byte[] P_ASSIGNED_PHONE2_req = {(byte) 90,(byte) 71,(byte) 186,(byte) 1,(byte) 93,(byte) 2};
    347            private final static byte[] P_ASSIGNED_PHONE2_LABEL_req = {(byte) 90,(byte) 71,(byte) 187,(byte) 1,(byte) 93,(byte) 2};
    348            private final static byte[] P_ASSIGNED_PHONE3_req = {(byte) 90,(byte) 71,(byte) 188,(byte) 1,(byte) 93,(byte) 2};
    349            private final static byte[] P_ASSIGNED_PHONE3_LABEL_req = {(byte) 90,(byte) 71,(byte) 189,(byte) 1,(byte) 93,(byte) 2};
    350            private final static byte[] P_POPULARITY_ORD_req = {(byte) 90,(byte) 71,(byte) 42,(byte) 93,(byte) 2};
    351            /** Properties of the Contact class */
    352            public enum Property implements PropertyEnumConverting {
    353                    P_UNKNOWN               (0,0,null,0,null),
    354                    P_TYPE                  (202, 1, P_TYPE_req, 0, Type.get(0)),
    355                    P_SKYPE_NAME            (4, 2, P_SKYPE_NAME_req, 0, null),
    356                    P_PSTN_NUMBER           (6, 3, P_PSTN_NUMBER_req, 0, null),
    357                    P_FULL_NAME             (5, 4, P_FULL_NAME_req, 0, null),
    358                    P_BIRTHDAY              (7, 5, P_BIRTHDAY_req, 0, null),
    359                    P_GENDER                (8, 6, P_GENDER_req, 0, null),
    360                    P_LANGUAGES             (9, 7, P_LANGUAGES_req, 0, null),
    361                    P_COUNTRY               (10, 8, P_COUNTRY_req, 0, null),
    362                    P_PROVINCE              (11, 9, P_PROVINCE_req, 0, null),
    363                    P_CITY                  (12, 10, P_CITY_req, 0, null),
    364                    P_PHONE_HOME            (13, 11, P_PHONE_HOME_req, 0, null),
    365                    P_PHONE_OFFICE          (14, 12, P_PHONE_OFFICE_req, 0, null),
    366                    P_PHONE_MOBILE          (15, 13, P_PHONE_MOBILE_req, 0, null),
    367                    P_EMAILS                (16, 14, P_EMAILS_req, 0, null),
    368                    P_HOMEPAGE              (17, 15, P_HOMEPAGE_req, 0, null),
    369                    P_ABOUT                 (18, 16, P_ABOUT_req, 0, null),
    370                    P_AVATAR_IMAGE          (37, 17, P_AVATAR_IMAGE_req, 0, null),
    371                    P_MOOD_TEXT             (26, 18, P_MOOD_TEXT_req, 0, null),
    372                    P_RICH_MOOD_TEXT        (205, 19, P_RICH_MOOD_TEXT_req, 0, null),
    373                    P_TIMEZONE              (27, 20, P_TIMEZONE_req, 0, null),
    374                    P_CAPABILITIES          (36, 21, P_CAPABILITIES_req, 0, null),
    375                    P_PROFILE_TIMESTAMP     (19, 22, P_PROFILE_TIMESTAMP_req, 0, null),
    376                    P_NROF_AUTHED_BUDDIES   (28, 23, P_NROF_AUTHED_BUDDIES_req, 0, null),
    377                    P_IP_COUNTRY            (29, 24, P_IP_COUNTRY_req, 0, null),
    378                    P_AVATAR_TIMESTAMP      (182, 25, P_AVATAR_TIMESTAMP_req, 0, null),
    379                    P_MOOD_TIMESTAMP        (183, 26, P_MOOD_TIMESTAMP_req, 0, null),
    380                    P_RECEIVED_AUTH_REQUEST (20, 27, P_RECEIVED_AUTH_REQUEST_req, 0, null),
    381                    P_AUTH_REQUEST_TIMESTAMP(25, 28, P_AUTH_REQUEST_TIMESTAMP_req, 0, null),
    382                    P_LAST_ONLINE_TIMESTAMP (35, 29, P_LAST_ONLINE_TIMESTAMP_req, 0, null),
    383                    P_AVAILABILITY          (34, 30, P_AVAILABILITY_req, 0, Availability.get(0)),
    384                    P_DISPLAY_NAME          (21, 31, P_DISPLAY_NAME_req, 0, null),
    385                    P_REFRESHING            (22, 32, P_REFRESHING_req, 0, null),
    386                    P_GIVEN_AUTH_LEVEL      (23, 33, P_GIVEN_AUTH_LEVEL_req, 0, AuthLevel.get(0)),
    387                    P_GIVEN_DISPLAY_NAME    (33, 34, P_GIVEN_DISPLAY_NAME_req, 0, null),
    388                    P_ASSIGNED_COMMENT      (180, 35, P_ASSIGNED_COMMENT_req, 0, null),
    389                    P_LAST_USED_TIMESTAMP   (39, 36, P_LAST_USED_TIMESTAMP_req, 0, null),
    390                    P_AUTH_REQUEST_COUNT    (41, 37, P_AUTH_REQUEST_COUNT_req, 0, null),
    391                    P_ASSIGNED_PHONE1       (184, 38, P_ASSIGNED_PHONE1_req, 0, null),
    392                    P_ASSIGNED_PHONE1_LABEL (185, 39, P_ASSIGNED_PHONE1_LABEL_req, 0, null),
    393                    P_ASSIGNED_PHONE2       (186, 40, P_ASSIGNED_PHONE2_req, 0, null),
    394                    P_ASSIGNED_PHONE2_LABEL (187, 41, P_ASSIGNED_PHONE2_LABEL_req, 0, null),                P_ASSIGNED_PHONE3       (188, 42, P_ASSIGNED_PHONE3_req, 0, null),
    395                    P_ASSIGNED_PHONE3_LABEL (189, 43, P_ASSIGNED_PHONE3_LABEL_req, 0, null),
    396                    P_POPULARITY_ORD        (42, 44, P_POPULARITY_ORD_req, 0, null);
    397                    private final int    key;
    398                    private final int    idx;
    399                    private final byte[] req;
    400                    private final int    mod;
    401                    private final EnumConverting enumConverter;
    402                    Property(int key, int idx, byte[] req, int mod, EnumConverting converter) {
    403                            this.key = key;
    404                            this.idx = idx;
    405                            this.req = req;
    406                            this.mod = mod;
    407                            this.enumConverter = converter;
    408                    };
    409                    public boolean  isCached()    { return idx > 0;   }
    410                    public int      getIdx()      { return idx;       }
    411                    public int      getId()       { return key;       }
    412                    public byte[]   getRequest()  { return req;       }
    413                    public EnumConverting getDefault()  { return P_UNKNOWN; }
    414                    public int      getModuleId() { return mod;       }
    415                    public EnumConverting getEnumConverter()    { return enumConverter;   }
    416                    public EnumConverting convert(final int from) { return Property.get(from); }
    417                    public EnumConverting[] getArray(final int size) { return new Property[size]; }
    418                    public static Property get(final int from) {
    419                            switch (from) {
    420                            case 202: return P_TYPE;
    421                            case   4: return P_SKYPE_NAME;
    422                            case   6: return P_PSTN_NUMBER;
    423                            case   5: return P_FULL_NAME;
    424                            case   7: return P_BIRTHDAY;
    425                            case   8: return P_GENDER;
    426                            case   9: return P_LANGUAGES;
    427                            case  10: return P_COUNTRY;
    428                            case  11: return P_PROVINCE;
    429                            case  12: return P_CITY;
    430                            case  13: return P_PHONE_HOME;
    431                            case  14: return P_PHONE_OFFICE;
    432                            case  15: return P_PHONE_MOBILE;
    433                            case  16: return P_EMAILS;
    434                            case  17: return P_HOMEPAGE;
    435                            case  18: return P_ABOUT;
    436                            case  37: return P_AVATAR_IMAGE;
    437                            case  26: return P_MOOD_TEXT;
    438                            case 205: return P_RICH_MOOD_TEXT;
    439                            case  27: return P_TIMEZONE;
    440                            case  36: return P_CAPABILITIES;
    441                            case  19: return P_PROFILE_TIMESTAMP;
    442                            case  28: return P_NROF_AUTHED_BUDDIES;
    443                            case  29: return P_IP_COUNTRY;
    444                            case 182: return P_AVATAR_TIMESTAMP;
    445                            case 183: return P_MOOD_TIMESTAMP;
    446                            case  20: return P_RECEIVED_AUTH_REQUEST;
    447                            case  25: return P_AUTH_REQUEST_TIMESTAMP;
    448                            case  35: return P_LAST_ONLINE_TIMESTAMP;
    449                            case  34: return P_AVAILABILITY;
    450                            case  21: return P_DISPLAY_NAME;
    451                            case  22: return P_REFRESHING;
    452                            case  23: return P_GIVEN_AUTH_LEVEL;
    453                            case  33: return P_GIVEN_DISPLAY_NAME;
    454                            case 180: return P_ASSIGNED_COMMENT;
    455                            case  39: return P_LAST_USED_TIMESTAMP;
    456                            case  41: return P_AUTH_REQUEST_COUNT;
    457                            case 184: return P_ASSIGNED_PHONE1;
    458                            case 185: return P_ASSIGNED_PHONE1_LABEL;
    459                            case 186: return P_ASSIGNED_PHONE2;
    460                            case 187: return P_ASSIGNED_PHONE2_LABEL;
    461                            case 188: return P_ASSIGNED_PHONE3;
    462                            case 189: return P_ASSIGNED_PHONE3_LABEL;
    463                            case  42: return P_POPULARITY_ORD;
    464                            }
    465                            return P_UNKNOWN;
    466                    }
    467                    public static final int P_TYPE_VALUE                   = 202;
    468                    public static final int P_SKYPE_NAME_VALUE             =   4;
    469                    public static final int P_PSTN_NUMBER_VALUE            =   6;
    470                    public static final int P_FULL_NAME_VALUE              =   5;
    471                    public static final int P_BIRTHDAY_VALUE               =   7;
    472                    public static final int P_GENDER_VALUE                 =   8;
    473                    public static final int P_LANGUAGES_VALUE              =   9;
    474                    public static final int P_COUNTRY_VALUE                =  10;
    475                    public static final int P_PROVINCE_VALUE               =  11;
    476                    public static final int P_CITY_VALUE                   =  12;
    477                    public static final int P_PHONE_HOME_VALUE             =  13;
    478                    public static final int P_PHONE_OFFICE_VALUE           =  14;
    479                    public static final int P_PHONE_MOBILE_VALUE           =  15;
    480                    public static final int P_EMAILS_VALUE                 =  16;
    481                    public static final int P_HOMEPAGE_VALUE               =  17;
    482                    public static final int P_ABOUT_VALUE                  =  18;
    483                    public static final int P_AVATAR_IMAGE_VALUE           =  37;
    484                    public static final int P_MOOD_TEXT_VALUE              =  26;
    485                    public static final int P_RICH_MOOD_TEXT_VALUE         = 205;
    486                    public static final int P_TIMEZONE_VALUE               =  27;
    487                    public static final int P_CAPABILITIES_VALUE           =  36;
    488                    public static final int P_PROFILE_TIMESTAMP_VALUE      =  19;
    489                    public static final int P_NROF_AUTHED_BUDDIES_VALUE    =  28;
    490                    public static final int P_IP_COUNTRY_VALUE             =  29;
    491                    public static final int P_AVATAR_TIMESTAMP_VALUE       = 182;
    492                    public static final int P_MOOD_TIMESTAMP_VALUE         = 183;
    493                    public static final int P_RECEIVED_AUTH_REQUEST_VALUE  =  20;
    494                    public static final int P_AUTH_REQUEST_TIMESTAMP_VALUE =  25;
    495                    public static final int P_LAST_ONLINE_TIMESTAMP_VALUE  =  35;
    496                    public static final int P_AVAILABILITY_VALUE           =  34;
    497                    public static final int P_DISPLAY_NAME_VALUE           =  21;
    498                    public static final int P_REFRESHING_VALUE             =  22;
    499                    public static final int P_GIVEN_AUTH_LEVEL_VALUE       =  23;
    500                    public static final int P_GIVEN_DISPLAY_NAME_VALUE     =  33;
    501                    public static final int P_ASSIGNED_COMMENT_VALUE       = 180;
    502                    public static final int P_LAST_USED_TIMESTAMP_VALUE    =  39;
    503                    public static final int P_AUTH_REQUEST_COUNT_VALUE     =  41;
    504                    public static final int P_ASSIGNED_PHONE1_VALUE        = 184;
    505                    public static final int P_ASSIGNED_PHONE1_LABEL_VALUE  = 185;
    506                    public static final int P_ASSIGNED_PHONE2_VALUE        = 186;
    507                    public static final int P_ASSIGNED_PHONE2_LABEL_VALUE  = 187;
    508                    public static final int P_ASSIGNED_PHONE3_VALUE        = 188;
    509                    public static final int P_ASSIGNED_PHONE3_LABEL_VALUE  = 189;
    510                    public static final int P_POPULARITY_ORD_VALUE         =  42;
    511                    public static final Property[] mget_info_mreq = { P_AVAILABILITY, P_DISPLAY_NAME };
    512                    public static final Property[] mget_profile_mreq = { P_SKYPE_NAME, P_PSTN_NUMBER, P_FULL_NAME, P_MOOD_TEXT, P_EMAILS, P_PHONE_HOME, P_PHONE_OFFICE, P_PHONE_MOBILE, P_BIRTHDAY, P_GENDER, P_LANGUAGES, P_COUNTRY, P_PROVINCE, P_CITY, P_HOMEPAGE, P_ABOUT, P_TIMEZONE };
    513            }
    514            private final static byte[] getIdentity_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 2};
    515            /**
    516             * getIdentity
    517             * @return identity returns CONTACT_SKYPENAME or CONTACT_PSTNNUMBER value
    518             */
    519            public String getIdentity() {
    520                    try {
    521                            return sidDoRequest(getIdentity_req)
    522                            .endRequest().getStringParm(1, true);
    523                    } catch(IOException e) {
    524                            mSidRoot.sidOnFatalError(e);
    525                            return ""
    526                    ;}
    527            }
    528            private final static byte[] getAvatar_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 4};
    529            public class GetAvatarResponse {
    530                    public boolean present;
    531                    public byte[] avatar;
    532            };
    533
    534            /** Returns Conrtact's avatar image (JPG).  * @return GetAvatarResponse
    535             * <br> - present
    536             *  - true: the Contact has a custom avatar image
    537             *  - false: the Contact does not have a custom avatar image
    538
    539             * <br> - avatar The avatar image data (JPG). If present is false, this will be the Skype-assigned default avatar
    540             */
    541            public GetAvatarResponse getAvatar() {
    542                    try {
    543                            Decoding decoder = sidDoRequest(getAvatar_req)
    544                            .endRequest();
    545                            GetAvatarResponse result = new GetAvatarResponse();
    546                            result.present = decoder.getBoolParm(1, false);
    547                            result.avatar = decoder.getBinaryParm(2, true);
    548                            return result;
    549                    } catch(IOException e) {
    550                            mSidRoot.sidOnFatalError(e);
    551                            return null
    552                    ;}
    553            }
    554            private final static byte[] getVerifiedEmail_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 3};
    555            /** returns verified-by-Skype e-mail for this contact if exists and verifiable * @return email
    556             */
    557            public String getVerifiedEmail() {
    558                    try {
    559                            return sidDoRequest(getVerifiedEmail_req)
    560                            .endRequest().getStringParm(1, true);
    561                    } catch(IOException e) {
    562                            mSidRoot.sidOnFatalError(e);
    563                            return ""
    564                    ;}
    565            }
    566            private final static byte[] getVerifiedCompany_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 8};
    567            /** returns verified-by-Skype company for this contact if exists and verifiable * @return company
    568             */
    569            public String getVerifiedCompany() {
    570                    try {
    571                            return sidDoRequest(getVerifiedCompany_req)
    572                            .endRequest().getStringParm(1, true);
    573                    } catch(IOException e) {
    574                            mSidRoot.sidOnFatalError(e);
    575                            return ""
    576                    ;}
    577            }
    578            private final static byte[] isMemberOf_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 6};
    579            /** Checks whether the contact is member of a contact group given in group reference argument.  * @param group The target contact group          * @return result
    580             *  - true: the Contact is a member of the target contact group
    581             *  - false: the Contact is not a member of the target contact group
    582
    583             */
    584            public boolean isMemberOf(ContactGroup group) {
    585                    try {
    586                            return sidDoRequest(isMemberOf_req)
    587                            .addObjectParm(1, group)
    588                            .endRequest().getBoolParm(1, true);
    589                    } catch(IOException e) {
    590                            mSidRoot.sidOnFatalError(e);
    591                            return false
    592                    ;}
    593            }
    594            private final static byte[] isMemberOfHardwiredGroup_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 7};
    595            /** Checks whether the contact is member of a pre-defined contact group given in the TYPE argument (type for this property comes from the ContactGroup class).  * @param groupType The type designator of the target pre-defined contact group. For example, specify this parameter as ContactGroup.TYPE.RECENTLY_CONTACTED_CONTACTS to determine if you've had a recent conversation with this Contact.
    596             * @return result
    597             *  - true: the Contact is a member of the target contact group
    598             *  - false: the Contact is not a member of the target contact group
    599
    600             */
    601            public boolean isMemberOfHardwiredGroup(ContactGroup.Type groupType) {
    602                    try {
    603                            return sidDoRequest(isMemberOfHardwiredGroup_req)
    604                            .addEnumParm(1, groupType)
    605                            .endRequest().getBoolParm(1, true);
    606                    } catch(IOException e) {
    607                            mSidRoot.sidOnFatalError(e);
    608                            return false
    609                    ;}
    610            }
    611            private final static byte[] setBlocked_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 22};
    612            /** Blocks or unblocks any further incoming communication attempts from this contact.  * @param blocked
    613             *  - true: block this contact
    614             *  - false: unblock this contact
    615
    616             * @param abuse Optional parameter to report abuse by this Skype user when blocking this Contact. Note that you can specifiy this parameter as true only when blocking a Contact. Defaults to false if omitted.
    617             */
    618            public void setBlocked(boolean blocked, boolean abuse) {
    619                    try {
    620                            sidDoRequest(setBlocked_req)
    621                            .addBoolParm(1, blocked)
    622                            .addBoolParm(2, abuse)
    623                            .endOneWay();
    624                    } catch(IOException e) {
    625                            mSidRoot.sidOnFatalError(e);
    626                    }
    627            }
    628            private final static byte[] ignoreAuthRequest_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 21};
    629            /** Rejects and removes a pending authorization request from this Contact.  */
    630            public void ignoreAuthRequest() {
    631                    try {
    632                            sidDoRequest(ignoreAuthRequest_req)
    633                            .endOneWay();
    634                    } catch(IOException e) {
    635                            mSidRoot.sidOnFatalError(e);
    636                    }
    637            }
    638            private final static byte[] giveDisplayName_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 10};
    639            /** sets CONTACT_GIVEN_DISPLAYNAME. clears if size(name)==0 * @param name
    640             */
    641            public void giveDisplayName(String name) {
    642                    try {
    643                            sidDoRequest(giveDisplayName_req)
    644                            .addStringParm(1, name)
    645                            .endOneWay();
    646                    } catch(IOException e) {
    647                            mSidRoot.sidOnFatalError(e);
    648                    }
    649            }
    650            private final static byte[] setBuddyStatus_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 12};
    651            /** Adds or removes this Contact from the ALL_BUDDIES hardwired group.  * @param isMyBuddy
    652             *  - true: add this contact to the ALL_BUDDIES group
    653             *  - false: delete contact from the ALL_BUDDIES group
    654
    655             * @param syncAuth This argument is deprecated and should not be used.
    656             */
    657            public void setBuddyStatus(boolean isMyBuddy, boolean syncAuth) {
    658                    try {
    659                            sidDoRequest(setBuddyStatus_req)
    660                            .addBoolParm(1, isMyBuddy)
    661                            .addBoolParm(2, syncAuth, true)
    662                            .endOneWay();
    663                    } catch(IOException e) {
    664                            mSidRoot.sidOnFatalError(e);
    665                    }
    666            }
    667            private final static byte[] sendAuthRequest_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 13};
    668            /** Sends a contact authorization request to this user.  * @param message Text that typically introduces the requesting user and details the reason for the authorization request. This text will be set as Message.P_BODY_XML property of the notification Message the remote user will receive upon getting the authortization request. While this can be the empty string, it cannot be null.
    669             * @param extrasBitmask Indicates additional information to include with this authorization request:
    670             *  - 0 (zero): do not include any additional information
    671             *  - SEND_VERIFIED_EMAIL: include the requestor's verified e-mail address
    672             *  - SEND_VERIFIED_COMPANY: include verified information regarding the requestor's company
    673             *  - SEND_VERIFIED_EMAIL + SEND_VERIFIED_COMPANY: include both e-mail and company information
    674
    675             */
    676            public void sendAuthRequest(String message, int extrasBitmask) {
    677                    try {
    678                            sidDoRequest(sendAuthRequest_req)
    679                            .addStringParm(1, message)
    680                            .addUintParm(2, extrasBitmask)
    681                            .endOneWay();
    682                    } catch(IOException e) {
    683                            mSidRoot.sidOnFatalError(e);
    684                    }
    685            }
    686            private final static byte[] hasAuthorizedMe_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 14};
    687            /** the contact has accepted my auth request * @return result
    688             */
    689            public boolean hasAuthorizedMe() {
    690                    try {
    691                            return sidDoRequest(hasAuthorizedMe_req)
    692                            .endRequest().getBoolParm(1, true);
    693                    } catch(IOException e) {
    694                            mSidRoot.sidOnFatalError(e);
    695                            return false
    696                    ;}
    697            }
    698            private final static byte[] setPhoneNumber_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 15};
    699            /**
    700             * Sets the three P_ASSIGNED_PHONEx and P_ASSIGNED_PHONEx_LABEL properties, where x reflects the value of num.
    701             *
    702             * The Skype Windows desktop client uses the following conventions when interpreting and assigning values to these properties. While your solution can assign arbitrary values to these properties, we strongly recommend using these conventions to ensure interoperability with the Skype Windows desktop client. Keep in mind that the "number" of these property pairs has no relationship to how the Skype Windows client interprets their label property value strings. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0".
    703             *
    704             * Label strings:
    705             *
    706             * Populate the label properties with string representations of the numbers "0" through "3", rather than descriptive strings like "Home", "Mobile", and so forth. The Skype desktop clients interpret the numeric string values as:
    707             *  - "0" (zero) - "Home"
    708             *  - "1" (one) - "Office"
    709             *  - "2" - "Mobile"
    710             *  - "3" - "Other"
    711             *
    712             * Keep in mind that the "number" of a property pair has no relationship to its label string. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0".
    713             *
    714             * Phone number strings:
    715             *
    716             * The Skype Windows desktop client has distinct conventions for Skype Contacts and PSTN (SkypeOut) Contacts: any or all of the property pairs can be used for Skype Contacts; P_ASSIGNED_PHONE1 cannot be used for PSTN Contacts and P_ASSIGNED_PHONE1_LABEL has special meaning for PSTN Contacts.
    717             * Specifically, the Skype desktop clients use P_ASSIGNED_PHONE1_LABEL as the label for a PSTN Contact's primary number (regardless of whether it's home, mobile, or office), and use P_PSTNNUMBER to hold the actual number.
    718             *
    719             * @param num The property pair being set, which must be in the range 0..3
    720             * @param label The label text for the property being set
    721             * @param number The phone number for the property being set
    722             */
    723            public void setPhoneNumber(int num, String label, String number) {
    724                    try {
    725                            sidDoRequest(setPhoneNumber_req)
    726                            .addUintParm(1, num)
    727                            .addStringParm(2, label)
    728                            .addStringParm(3, number)
    729                            .endOneWay();
    730                    } catch(IOException e) {
    731                            mSidRoot.sidOnFatalError(e);
    732                    }
    733            }
    734            private final static byte[] openConversation_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 17};
    735            /** Retrieves a dialog conversation with the Contact.  * @return conversation Retrieved dialog.
    736             */
    737            public Conversation openConversation() {
    738                    try {
    739                            return (Conversation) sidDoRequest(openConversation_req)
    740                            .endRequest().getObjectParm(1, 18, true);
    741                    } catch(IOException e) {
    742                            mSidRoot.sidOnFatalError(e);
    743                            return null
    744                    ;}
    745            }
    746            private final static byte[] hasCapability_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 18};
    747            /** Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server. This method is functionally the same as Contact.GetCapabilityStatus except that it returns a bool value rather than Contact.CAPABILITYSTATUS  * @param capability The target capability          * @param queryServer
    748             *  - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration
    749             *  - false: obtains the data from the local client
    750
    751             * @return result
    752             *  - true: the Contact has the target capability through at least one of the Skype clients they have logged into. Corresponds to CAPABILITY_MIXED and CAPABILITY_EXISTS
    753             *  - false: the Contact does not have the target capability. Corresponds to NO_CAPABILITY
    754
    755             */
    756            public boolean hasCapability(Capability capability, boolean queryServer) {
    757                    try {
    758                            return sidDoRequest(hasCapability_req)
    759                            .addEnumParm(1, capability)
    760                            .addBoolParm(2, queryServer)
    761                            .endRequest().getBoolParm(1, true);
    762                    } catch(IOException e) {
    763                            mSidRoot.sidOnFatalError(e);
    764                            return false
    765                    ;}
    766            }
    767            private final static byte[] getCapabilityStatus_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 19};
    768            /** Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server.  * @param capability The target capability, see Contact.Capability enumerator.
    769             * @param queryServer
    770             *  - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration
    771             *  - false: obtains the data from the local client
    772
    773             * @return status Status of the target capability.
    774             */
    775            public Capabilitystatus getCapabilityStatus(Capability capability, boolean queryServer) {
    776                    try {
    777                            return (Capabilitystatus) sidDoRequest(getCapabilityStatus_req)
    778                            .addEnumParm(1, capability)
    779                            .addBoolParm(2, queryServer)
    780                            .endRequest().getEnumParm(1, Capabilitystatus.get(0), true);
    781                    } catch(IOException e) {
    782                            mSidRoot.sidOnFatalError(e);
    783                            return Capabilitystatus.get(0)
    784                    ;}
    785            }
    786            private final static byte[] refreshProfile_req = {(byte) 90,(byte) 82,(byte) 2,(byte) 20};
    787            /** Refreshes all properties, capabilities, and statuses associated with this Contact from p2p/CBL, and sets P_REFRESHING to true for the duration.  */
    788            public void refreshProfile() {
    789                    try {
    790                            sidDoRequest(refreshProfile_req)
    791                            .endOneWay();
    792                    } catch(IOException e) {
    793                            mSidRoot.sidOnFatalError(e);
    794                    }
    795            }
    796            /***
    797             * generic multiget of a list of Property
    798             * @param requested the list of requested properties of Contact
    799             * @return SidGetResponding
    800             */
    801            public SidGetResponding sidMultiGet(Property[] requested) {
    802                    return super.sidMultiGet(requested);
    803            }
    804            /***
    805             * generic multiget of list of Property for a list of Contact
    806             * @param requested the list of requested properties
    807             * @return SidGetResponding[] can be casted to (Contact[]) if all properties are cached
    808             */
    809            static public SidGetResponding[] sidMultiGet(Property[] requested, Contact[] objects) {
    810                    return SidObject.sidMultiGet(requested, objects);
    811            }
    812            /*** multiget the following properties
    813             * - P_AVAILABILITY
    814             * - P_DISPLAY_NAME
    815             */
    816            public Contact mgetInfo() {
    817                    return (Contact) super.sidMultiGet(Property.mget_info_mreq, this);
    818            }
    819            /*** multiget the following properties for a list of Contact
    820             * - P_AVAILABILITY
    821             * - P_DISPLAY_NAME
    822             * @param objects targets of the request
    823             * @return Contact[] responses
    824             */
    825            static public Contact[] mgetInfo(Contact[] objects) {
    826                    return (Contact[]) SidObject.sidMultiGet(Property.mget_info_mreq, objects, objects);
    827            }
    828            /*** multiget the following properties
    829             * - P_SKYPE_NAME
    830             * - P_PSTN_NUMBER
    831             * - P_FULL_NAME
    832             * - P_MOOD_TEXT
    833             * - P_EMAILS
    834             * - P_PHONE_HOME
    835             * - P_PHONE_OFFICE
    836             * - P_PHONE_MOBILE
    837             * - P_BIRTHDAY
    838             * - P_GENDER
    839             * - P_LANGUAGES
    840             * - P_COUNTRY
    841             * - P_PROVINCE
    842             * - P_CITY
    843             * - P_HOMEPAGE
    844             * - P_ABOUT
    845             * - P_TIMEZONE
    846             */
    847            public Contact mgetProfile() {
    848                    return (Contact) super.sidMultiGet(Property.mget_profile_mreq, this);
    849            }
    850            public Type getType() {
    851                    synchronized(this) {
    852                            if ((mSidCached & 0x1) != 0)
    853                                    return mType;
    854                    }
    855                    return (Type) sidRequestEnumProperty(Property.P_TYPE);
    856            }
    857            /** defined if it is a SKYPE contact */
    858            public String getSkypeName() {
    859                    synchronized(this) {
    860                            if ((mSidCached & 0x2) != 0)
    861                                    return mSkypeName;
    862                    }
    863                    return sidRequestStringProperty(Property.P_SKYPE_NAME);
    864            }
    865            public String getPstnNumber() {
    866                    synchronized(this) {
    867                            if ((mSidCached & 0x4) != 0)
    868                                    return mPstnNumber;
    869                    }
    870                    return sidRequestStringProperty(Property.P_PSTN_NUMBER);
    871            }
    872            public String getFullName() {
    873                    synchronized(this) {
    874                            if ((mSidCached & 0x8) != 0)
    875                                    return mFullName;
    876                    }
    877                    return sidRequestStringProperty(Property.P_FULL_NAME);
    878            }
    879            /** integer of YYYYMMDD format */
    880            public int getBirthday() {
    881                    synchronized(this) {
    882                            if ((mSidCached & 0x10) != 0)
    883                                    return mBirthday;
    884                    }
    885                    return sidRequestUintProperty(Property.P_BIRTHDAY);
    886            }
    887            /** 1-male, 2-female */
    888            public int getGender() {
    889                    synchronized(this) {
    890                            if ((mSidCached & 0x20) != 0)
    891                                    return mGender;
    892                    }
    893                    return sidRequestUintProperty(Property.P_GENDER);
    894            }
    895            /** ISO language code list, space separated */
    896            public String getLanguages() {
    897                    synchronized(this) {
    898                            if ((mSidCached & 0x40) != 0)
    899                                    return mLanguages;
    900                    }
    901                    return sidRequestStringProperty(Property.P_LANGUAGES);
    902            }
    903            /** ISO country code */
    904            public String getCountry() {
    905                    synchronized(this) {
    906                            if ((mSidCached & 0x80) != 0)
    907                                    return mCountry;
    908                    }
    909                    return sidRequestStringProperty(Property.P_COUNTRY);
    910            }
    911            public String getProvince() {
    912                    synchronized(this) {
    913                            if ((mSidCached & 0x100) != 0)
    914                                    return mProvince;
    915                    }
    916                    return sidRequestStringProperty(Property.P_PROVINCE);
    917            }
    918            public String getCity() {
    919                    synchronized(this) {
    920                            if ((mSidCached & 0x200) != 0)
    921                                    return mCity;
    922                    }
    923                    return sidRequestStringProperty(Property.P_CITY);
    924            }
    925            /** This corresponds to the Account.P_PHONE_HOME property. The value is set by the remote user in Account profile. As Contact property, this is read-only.  */
    926            public String getPhoneHome() {
    927                    synchronized(this) {
    928                            if ((mSidCached & 0x400) != 0)
    929                                    return mPhoneHome;
    930                    }
    931                    return sidRequestStringProperty(Property.P_PHONE_HOME);
    932            }
    933            /** This corresponds to the Account.P_PHONE_OFFICE property. The value is set by the remote user in Account profile. As Contact property, this is read-only. If the Contact has not populated his Account profile with sufficient phone numbers, the UI should implement locally adding additional phone numbers to Contact P_ASSIGNED_PHONE1 .. P_ASSIGNED_PHONE3 properties (and corresponding labels). See Contact.SetPhoneNumber method for more information.  */
    934            public String getPhoneOffice() {
    935                    synchronized(this) {
    936                            if ((mSidCached & 0x800) != 0)
    937                                    return mPhoneOffice;
    938                    }
    939                    return sidRequestStringProperty(Property.P_PHONE_OFFICE);
    940            }
    941            /** This corresponds to the Account.P_PHONE_MOBILE property. The value is set by the remote user in Account profile. As Contact property, this is read-only.  */
    942            public String getPhoneMobile() {
    943                    synchronized(this) {
    944                            if ((mSidCached & 0x1000) != 0)
    945                                    return mPhoneMobile;
    946                    }
    947                    return sidRequestStringProperty(Property.P_PHONE_MOBILE);
    948            }
    949            /** will be hashed before advertising/querying, space separated */
    950            public String getEmails() {
    951                    synchronized(this) {
    952                            if ((mSidCached & 0x2000) != 0)
    953                                    return mEmails;
    954                    }
    955                    return sidRequestStringProperty(Property.P_EMAILS);
    956            }
    957            public String getHomepage() {
    958                    synchronized(this) {
    959                            if ((mSidCached & 0x4000) != 0)
    960                                    return mHomepage;
    961                    }
    962                    return sidRequestStringProperty(Property.P_HOMEPAGE);
    963            }
    964            /** arbitrary introductory text */
    965            public String getAbout() {
    966                    synchronized(this) {
    967                            if ((mSidCached & 0x8000) != 0)
    968                                    return mAbout;
    969                    }
    970                    return sidRequestStringProperty(Property.P_ABOUT);
    971            }
    972            /** Contact avatar pictures are in JPG format. The original size of avatar pictures are in no more than 96 x 96 pixels in size. However, as they can be smaller, scaling the pictures up too much to fit your UI can lead to distorted images.  */
    973            public byte[] getAvatarImage() {
    974                    synchronized(this) {
    975                            if ((mSidCached & 0x10000) != 0)
    976                                    return mAvatarImage;
    977                    }
    978                    return sidRequestBinaryProperty(Property.P_AVATAR_IMAGE);
    979            }
    980            /** Personal mood message (visible to authorized users only).   */
    981            public String getMoodText() {
    982                    synchronized(this) {
    983                            if ((mSidCached & 0x20000) != 0)
    984                                    return mMoodText;
    985                    }
    986                    return sidRequestStringProperty(Property.P_MOOD_TEXT);
    987            }
    988            /** XML version of personal mood text */        public String getRichMoodText() {
    989                    synchronized(this) {
    990                            if ((mSidCached & 0x40000) != 0)
    991                                    return mRichMoodText;
    992                    }
    993                    return sidRequestXmlProperty(Property.P_RICH_MOOD_TEXT);
    994            }
    995            /** 24*3600+diff_to_UTC_in_seconds. NB! changes with DST  */
    996            public int getTimezone() {
    997                    synchronized(this) {
    998                            if ((mSidCached & 0x80000) != 0)
    999                                    return mTimezone;
    1000                    }
    1001                    return sidRequestUintProperty(Property.P_TIMEZONE);
    1002            }
    1003            /** binary tag that can be queried via Contact.HasCapability() */
    1004            public byte[] getCapabilities() {
    1005                    synchronized(this) {
    1006                            if ((mSidCached & 0x100000) != 0)
    1007                                    return mCapabilities;
    1008                    }
    1009                    return sidRequestBinaryProperty(Property.P_CAPABILITIES);
    1010            }
    1011            /** UNIX timestamp of last profile change */
    1012            public int getProfileTimestamp() {
    1013                    synchronized(this) {
    1014                            if ((mSidCached & 0x200000) != 0)
    1015                                    return mProfileTimestamp;
    1016                    }
    1017                    return sidRequestUintProperty(Property.P_PROFILE_TIMESTAMP);
    1018            }
    1019            /** count of this user's authorized contacts  */
    1020            public int getNrofAuthedBuddies() {
    1021                    synchronized(this) {
    1022                            if ((mSidCached & 0x400000) != 0)
    1023                                    return mNrofAuthedBuddies;
    1024                    }
    1025                    return sidRequestUintProperty(Property.P_NROF_AUTHED_BUDDIES);
    1026            }
    1027            /** ISO country code assigned by the IP */
    1028            public String getIpCountry() {
    1029                    synchronized(this) {
    1030                            if ((mSidCached & 0x800000) != 0)
    1031                                    return mIpCountry;
    1032                    }
    1033                    return sidRequestStringProperty(Property.P_IP_COUNTRY);
    1034            }
    1035            /** UNIX timestamp of when current avatar was set */
    1036            public int getAvatarTimestamp() {
    1037                    synchronized(this) {
    1038                            if ((mSidCached & 0x1000000) != 0)
    1039                                    return mAvatarTimestamp;
    1040                    }
    1041                    return sidRequestUintProperty(Property.P_AVATAR_TIMESTAMP);
    1042            }
    1043            /** NOT SET FOR CONTACTS. For Account object, UNIX timestamp of when current mood was set */
    1044            public int getMoodTimestamp() {
    1045                    synchronized(this) {
    1046                            if ((mSidCached & 0x2000000) != 0)
    1047                                    return mMoodTimestamp;
    1048                    }
    1049                    return sidRequestUintProperty(Property.P_MOOD_TIMESTAMP);
    1050            }
    1051            /** set if the contact is waiting to be authorized. The value contains auth. request text  */
    1052            public String getReceivedAuthRequest() {
    1053                    synchronized(this) {
    1054                            if ((mSidCached & 0x4000000) != 0)
    1055                                    return mReceivedAuthRequest;
    1056                    }
    1057                    return sidRequestStringProperty(Property.P_RECEIVED_AUTH_REQUEST);
    1058            }
    1059            /** timestamp of last received auth-request */
    1060            public int getAuthRequestTimestamp() {
    1061                    synchronized(this) {
    1062                            if ((mSidCached & 0x8000000) != 0)
    1063                                    return mAuthRequestTimestamp;
    1064                    }
    1065                    return sidRequestUintProperty(Property.P_AUTH_REQUEST_TIMESTAMP);
    1066            }
    1067            /** X timestamp of last successful ping to that user */
    1068            public int getLastOnlineTimestamp() {
    1069                    synchronized(this) {
    1070                            if ((mSidCached & 0x10000000) != 0)
    1071                                    return mLastOnlineTimestamp;
    1072                    }
    1073                    return sidRequestUintProperty(Property.P_LAST_ONLINE_TIMESTAMP);
    1074            }
    1075            /** Contact.AVAILABILITY */
    1076            public Availability getAvailability() {
    1077                    synchronized(this) {
    1078                            if ((mSidCached & 0x20000000) != 0)
    1079                                    return mAvailability;
    1080                    }
    1081                    return (Availability) sidRequestEnumProperty(Property.P_AVAILABILITY);
    1082            }
    1083            /** always set (assigned by lib by looking at various fields) */
    1084            public String getDisplayName() {
    1085                    synchronized(this) {
    1086                            if ((mSidCached & 0x40000000) != 0)
    1087                                    return mDisplayName;
    1088                    }
    1089                    return sidRequestStringProperty(Property.P_DISPLAY_NAME);
    1090            }
    1091            /** true if querying additional information from p2p or server  */
    1092            public boolean getRefreshing() {
    1093                    synchronized(this) {
    1094                            if ((mSidCached & 0x80000000) != 0)
    1095                                    return mRefreshing;
    1096                    }
    1097                    return sidRequestBoolProperty(Property.P_REFRESHING);
    1098            }
    1099            /** Contact.AUTHLEVEL, change via Contact.GiveAuthlevel() */
    1100            public AuthLevel getGivenAuthLevel() {
    1101                    synchronized(this) {
    1102                            if ((mSidExtraCached[0] & 0x1) != 0)
    1103                                    return mGivenAuthLevel;
    1104                    }
    1105                    return (AuthLevel) sidRequestEnumProperty(Property.P_GIVEN_AUTH_LEVEL);
    1106            }
    1107            /** change via Contact.GiveDisplayname() */
    1108            public String getGivenDisplayName() {
    1109                    synchronized(this) {
    1110                            if ((mSidExtraCached[0] & 0x2) != 0)
    1111                                    return mGivenDisplayName;
    1112                    }
    1113                    return sidRequestStringProperty(Property.P_GIVEN_DISPLAY_NAME);
    1114            }
    1115            /** change via Contact.AssignComment() */
    1116            public String getAssignedComment() {
    1117                    synchronized(this) {
    1118                            if ((mSidExtraCached[0] & 0x4) != 0)
    1119                                    return mAssignedComment;
    1120                    }
    1121                    return sidRequestStringProperty(Property.P_ASSIGNED_COMMENT);
    1122            }
    1123            /** UNIX timestamp of last outbound session (call, chat, FT, etc) */
    1124            public int getLastUsedTimestamp() {
    1125                    synchronized(this) {
    1126                            if ((mSidExtraCached[0] & 0x8) != 0)
    1127                                    return mLastUsedTimestamp;
    1128                    }
    1129                    return sidRequestUintProperty(Property.P_LAST_USED_TIMESTAMP);
    1130            }
    1131            /** for contacts that have CONTACT_RECEIVED_AUTHREQUEST, how many times in a row they have requested it without positive answer */
    1132            public int getAuthRequestCount() {
    1133                    synchronized(this) {
    1134                            if ((mSidExtraCached[0] & 0x10) != 0)
    1135                                    return mAuthRequestCount;
    1136                    }
    1137                    return sidRequestUintProperty(Property.P_AUTH_REQUEST_COUNT);
    1138            }
    1139            /** Office phone no. of the contact. This property should NOT be used for SkypeOut contacts  */
    1140            public String getAssignedPhone1() {
    1141                    synchronized(this) {
    1142                            if ((mSidExtraCached[0] & 0x20) != 0)
    1143                                    return mAssignedPhone1;
    1144                    }
    1145                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE1);
    1146            }
    1147            /** Value "1" in this property will be translated as "Office" by Skype Windows desktop client, according to UI language settings  */
    1148            public String getAssignedPhone1Label() {
    1149                    synchronized(this) {
    1150                            if ((mSidExtraCached[0] & 0x40) != 0)
    1151                                    return mAssignedPhone1Label;
    1152                    }
    1153                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE1_LABEL);
    1154            }
    1155            /** Mobile phone no. of the contact  */
    1156            public String getAssignedPhone2() {
    1157                    synchronized(this) {
    1158                            if ((mSidExtraCached[0] & 0x80) != 0)
    1159                                    return mAssignedPhone2;
    1160                    }
    1161                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE2);
    1162            }
    1163            /** Value "2" in this property will be translated as "Mobile" by Skype Windows desktop client, according to UI language settings  */
    1164            public String getAssignedPhone2Label() {
    1165                    synchronized(this) {
    1166                            if ((mSidExtraCached[0] & 0x100) != 0)
    1167                                    return mAssignedPhone2Label;
    1168                    }
    1169                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE2_LABEL);
    1170            }
    1171            /** "Other phone no. of the contact */
    1172            public String getAssignedPhone3() {
    1173                    synchronized(this) {
    1174                            if ((mSidExtraCached[0] & 0x200) != 0)
    1175                                    return mAssignedPhone3;
    1176                    }
    1177                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE3);
    1178            }
    1179            /** Value "3" in this property will be translated as "Other" by Skype Windows desktop client, according to UI language settings  */
    1180            public String getAssignedPhone3Label() {
    1181                    synchronized(this) {
    1182                            if ((mSidExtraCached[0] & 0x400) != 0)
    1183                                    return mAssignedPhone3Label;
    1184                    }
    1185                    return sidRequestStringProperty(Property.P_ASSIGNED_PHONE3_LABEL);
    1186            }
    1187            /** Contact's order by presence popularity  */
    1188            public int getPopularityOrd() {
    1189                    synchronized(this) {
    1190                            if ((mSidExtraCached[0] & 0x800) != 0)
    1191                                    return mPopularityOrd;
    1192                    }
    1193                    return sidRequestUintProperty(Property.P_POPULARITY_ORD);
    1194            }
    1195            public String sidGetStringProperty(final PropertyEnumConverting prop) {
    1196                    switch(prop.getId()) {
    1197                    case 4:
    1198                            return mSkypeName;
    1199                    case 6:
    1200                            return mPstnNumber;
    1201                    case 5:
    1202                            return mFullName;
    1203                    case 9:
    1204                            return mLanguages;
    1205                    case 10:
    1206                            return mCountry;
    1207                    case 11:
    1208                            return mProvince;
    1209                    case 12:
    1210                            return mCity;
    1211                    case 13:
    1212                            return mPhoneHome;
    1213                    case 14:
    1214                            return mPhoneOffice;
    1215                    case 15:
    1216                            return mPhoneMobile;
    1217                    case 16:
    1218                            return mEmails;
    1219                    case 17:
    1220                            return mHomepage;
    1221                    case 18:
    1222                            return mAbout;
    1223                    case 26:
    1224                            return mMoodText;
    1225                    case 205:
    1226                            return mRichMoodText;
    1227                    case 29:
    1228                            return mIpCountry;
    1229                    case 20:
    1230                            return mReceivedAuthRequest;
    1231                    case 21:
    1232                            return mDisplayName;
    1233                    case 33:
    1234                            return mGivenDisplayName;
    1235                    case 180:
    1236                            return mAssignedComment;
    1237                    case 184:
    1238                            return mAssignedPhone1;
    1239                    case 185:
    1240                            return mAssignedPhone1Label;
    1241                    case 186:
    1242                            return mAssignedPhone2;
    1243                    case 187:
    1244                            return mAssignedPhone2Label;
    1245                    case 188:
    1246                            return mAssignedPhone3;
    1247                    case 189:
    1248                            return mAssignedPhone3Label;
    1249                    }
    1250                    return "";
    1251            }
    1252            public boolean sidGetBoolProperty(final PropertyEnumConverting prop) {
    1253                    assert(prop.getId() == 22);
    1254                    return mRefreshing;
    1255            }
    1256            public int sidGetIntProperty(final PropertyEnumConverting prop) {
    1257                    switch(prop.getId()) {
    1258                    case 7:                 return mBirthday;
    1259                    case 8:
    1260                            return mGender;
    1261                    case 27:
    1262                            return mTimezone;
    1263                    case 19:
    1264                            return mProfileTimestamp;
    1265                    case 28:
    1266                            return mNrofAuthedBuddies;
    1267                    case 182:
    1268                            return mAvatarTimestamp;
    1269                    case 183:
    1270                            return mMoodTimestamp;
    1271                    case 25:
    1272                            return mAuthRequestTimestamp;
    1273                    case 35:
    1274                            return mLastOnlineTimestamp;
    1275                    case 39:
    1276                            return mLastUsedTimestamp;
    1277                    case 41:
    1278                            return mAuthRequestCount;
    1279                    case 42:
    1280                            return mPopularityOrd;
    1281                    }
    1282                    return 0;
    1283            }
    1284            public EnumConverting sidGetEnumProperty(final PropertyEnumConverting prop) {
    1285                    switch(prop.getId()) {
    1286                    case 202:
    1287                            return mType;
    1288                    case 34:
    1289                            return mAvailability;
    1290                    case 23:
    1291                            return mGivenAuthLevel;
    1292                    }
    1293                    return null;
    1294            }
    1295            public byte[] sidGetBinaryProperty(final PropertyEnumConverting prop) {
    1296                    switch(prop.getId()) {
    1297                    case 37:
    1298                            return mAvatarImage;
    1299                    case 36:
    1300                            return mCapabilities;
    1301                    }
    1302                    return null;
    1303            }
    1304            public String getPropertyAsString(final int prop) {
    1305                    switch (prop) {
    1306                    case 202: return getType().toString();
    1307                    case 4: return getSkypeName();
    1308                    case 6: return getPstnNumber();
    1309                    case 5: return getFullName();
    1310                    case 7: return Integer.toString(getBirthday());
    1311                    case 8: return Integer.toString(getGender());
    1312                    case 9: return getLanguages();
    1313                    case 10: return getCountry();
    1314                    case 11: return getProvince();
    1315                    case 12: return getCity();
    1316                    case 13: return getPhoneHome();
    1317                    case 14: return getPhoneOffice();
    1318                    case 15: return getPhoneMobile();
    1319                    case 16: return getEmails();
    1320                    case 17: return getHomepage();
    1321                    case 18: return getAbout();
    1322                    case 37: return "<binary>";
    1323                    case 26: return getMoodText();
    1324                    case 27: return Integer.toString(getTimezone());
    1325                    case 36: return "<binary>";
    1326                    case 19: return Integer.toString(getProfileTimestamp());
    1327                    case 28: return Integer.toString(getNrofAuthedBuddies());
    1328                    case 29: return getIpCountry();
    1329                    case 182: return Integer.toString(getAvatarTimestamp());
    1330                    case 183: return Integer.toString(getMoodTimestamp());
    1331                    case 20: return getReceivedAuthRequest();
    1332                    case 25: return Integer.toString(getAuthRequestTimestamp());
    1333                    case 35: return Integer.toString(getLastOnlineTimestamp());
    1334                    case 34: return getAvailability().toString();
    1335                    case 21: return getDisplayName();
    1336                    case 22: return Boolean.toString(getRefreshing());
    1337                    case 23: return getGivenAuthLevel().toString();
    1338                    case 33: return getGivenDisplayName();
    1339                    case 180: return getAssignedComment();
    1340                    case 39: return Integer.toString(getLastUsedTimestamp());
    1341                    case 41: return Integer.toString(getAuthRequestCount());
    1342                    case 184: return getAssignedPhone1();
    1343                    case 185: return getAssignedPhone1Label();
    1344                    case 186: return getAssignedPhone2();
    1345                    case 187: return getAssignedPhone2Label();
    1346                    case 188: return getAssignedPhone3();
    1347                    case 189: return getAssignedPhone3Label();
    1348                    case 42: return Integer.toString(getPopularityOrd());
    1349                    }
    1350                    return "<unkown>";
    1351            }
    1352            public String getPropertyAsString(final Property prop) {
    1353                    return getPropertyAsString(prop.getId());
    1354            }
    1355            protected void sidOnChangedProperty(final int propertyId, final int value, final String svalue) {
    1356                    final Property property = Property.get(propertyId);
    1357                    if (property == Property.P_UNKNOWN) return;
    1358                    final int idx = property.getIdx();
    1359                    if (idx != 0) {
    1360                            int word = (idx-1) / 32;
    1361                            int bit  = 1<<((idx-1)%32);
    1362                            synchronized (this) {
    1363                                    if (word == 0) mSidCached |= bit; else mSidExtraCached[word-1] |= bit;
    1364                                    switch (propertyId) {
    1365                                    case 202: mType = Type.get(value); break;
    1366                                    case 4:
    1367                                            if (svalue != null) mSkypeName = svalue;
    1368                                            else mSidCached &=~bit;
    1369                                            break;
    1370                                    case 6:
    1371                                            if (svalue != null) mPstnNumber = svalue;
    1372                                            else mSidCached &=~bit;
    1373                                            break;
    1374                                    case 5:
    1375                                            if (svalue != null) mFullName = svalue;
    1376                                            else mSidCached &=~bit;
    1377                                            break;
    1378                                    case 7: mBirthday = value; break;
    1379                                    case 8: mGender = value; break;
    1380                                    case 9:
    1381                                            if (svalue != null) mLanguages = svalue;
    1382                                            else mSidCached &=~bit;
    1383                                            break;
    1384                                    case 10:
    1385                                            if (svalue != null) mCountry = svalue;
    1386                                            else mSidCached &=~bit;
    1387                                            break;
    1388                                    case 11:
    1389                                            if (svalue != null) mProvince = svalue;
    1390                                            else mSidCached &=~bit;
    1391                                            break;
    1392                                    case 12:
    1393                                            if (svalue != null) mCity = svalue;
    1394                                            else mSidCached &=~bit;
    1395                                            break;
    1396                                    case 13:
    1397                                            if (svalue != null) mPhoneHome = svalue;
    1398                                            else mSidCached &=~bit;
    1399                                            break;
    1400                                    case 14:
    1401                                            if (svalue != null) mPhoneOffice = svalue;
    1402                                            else mSidCached &=~bit;
    1403                                            break;
    1404                                    case 15:
    1405                                            if (svalue != null) mPhoneMobile = svalue;
    1406                                            else mSidCached &=~bit;
    1407                                            break;
    1408                                    case 16:
    1409                                            if (svalue != null) mEmails = svalue;
    1410                                            else mSidCached &=~bit;
    1411                                            break;
    1412                                    case 17:
    1413                                            if (svalue != null) mHomepage = svalue;
    1414                                            else mSidCached &=~bit;
    1415                                            break;
    1416                                    case 18:
    1417                                            if (svalue != null) mAbout = svalue;
    1418                                            else mSidCached &=~bit;
    1419                                            break;
    1420                                    case 26:
    1421                                            if (svalue != null) mMoodText = svalue;
    1422                                            else mSidCached &=~bit;
    1423                                            break;
    1424                                    case 27: mTimezone = value; break;
    1425                                    case 19: mProfileTimestamp = value; break;
    1426                                    case 28: mNrofAuthedBuddies = value; break;
    1427                                    case 29:
    1428                                            if (svalue != null) mIpCountry = svalue;
    1429                                            else mSidCached &=~bit;
    1430                                            break;
    1431                                    case 182: mAvatarTimestamp = value; break;
    1432                                    case 183: mMoodTimestamp = value; break;
    1433                                    case 20:
    1434                                            if (svalue != null) mReceivedAuthRequest = svalue;
    1435                                            else mSidCached &=~bit;
    1436                                            break;
    1437                                    case 25: mAuthRequestTimestamp = value; break;
    1438                                    case 35: mLastOnlineTimestamp = value; break;
    1439                                    case 34: mAvailability = Availability.get(value); break;
    1440                                    case 21:
    1441                                            if (svalue != null) mDisplayName = svalue;
    1442                                            else mSidCached &=~bit;
    1443                                            break;
    1444                                    case 22: mRefreshing = value != 0; break;
    1445                                    case 23: mGivenAuthLevel = AuthLevel.get(value); break;
    1446                                    case 33:
    1447                                            if (svalue != null) mGivenDisplayName = svalue;
    1448                                            else mSidExtraCached[0] &=~bit;
    1449                                            break;
    1450                                    case 180:
    1451                                            if (svalue != null) mAssignedComment = svalue;
    1452                                            else mSidExtraCached[0] &=~bit;
    1453                                            break;
    1454                                    case 39: mLastUsedTimestamp = value; break;
    1455                                    case 41: mAuthRequestCount = value; break;
    1456                                    case 184:
    1457                                            if (svalue != null) mAssignedPhone1 = svalue;
    1458                                            else mSidExtraCached[0] &=~bit;
    1459                                            break;
    1460                                    case 185:
    1461                                            if (svalue != null) mAssignedPhone1Label = svalue;
    1462                                            else mSidExtraCached[0] &=~bit;
    1463                                            break;
    1464                                    case 186:
    1465                                            if (svalue != null) mAssignedPhone2 = svalue;
    1466                                            else mSidExtraCached[0] &=~bit;
    1467                                            break;
    1468                                    case 187:
    1469                                            if (svalue != null) mAssignedPhone2Label = svalue;
    1470                                            else mSidExtraCached[0] &=~bit;
    1471                                            break;
    1472                                    case 188:
    1473                                            if (svalue != null) mAssignedPhone3 = svalue;
    1474                                            else mSidExtraCached[0] &=~bit;
    1475                                            break;
    1476                                    case 189:
    1477                                            if (svalue != null) mAssignedPhone3Label = svalue;
    1478                                            else mSidExtraCached[0] &=~bit;
    1479                                            break;
    1480                                    case 42: mPopularityOrd = value; break;
    1481                                    default: if (word == 0) mSidCached &= bit; else mSidExtraCached[word-1] &= ~bit; break;
    1482                                    }
    1483                            }
    1484                    }
    1485                    ContactListener listener = ((Skype) mSidRoot).getContactListener();
    1486                    if (listener != null)
    1487                            listener.onPropertyChange(this, property, value, svalue);
    1488            }
    1489            public void sidSetProperty(final PropertyEnumConverting prop, final String newValue) {
    1490                    final int propId = prop.getId();
    1491                    switch(propId) {
    1492                    case 4:
    1493                            mSidCached |= 0x2;
    1494                            mSkypeName=  newValue;
    1495                            break;
    1496                    case 6:
    1497                            mSidCached |= 0x4;
    1498                            mPstnNumber=  newValue;
    1499                            break;
    1500                    case 5:
    1501                            mSidCached |= 0x8;
    1502                            mFullName=  newValue;
    1503                            break;
    1504                    case 9:
    1505                            mSidCached |= 0x40;
    1506                            mLanguages=  newValue;
    1507                            break;
    1508                    case 10:
    1509                            mSidCached |= 0x80;
    1510                            mCountry=  newValue;
    1511                            break;
    1512                    case 11:
    1513                            mSidCached |= 0x100;
    1514                            mProvince=  newValue;
    1515                            break;
    1516                    case 12:
    1517                            mSidCached |= 0x200;
    1518                            mCity=  newValue;
    1519                            break;
    1520                    case 13:
    1521                            mSidCached |= 0x400;
    1522                            mPhoneHome=  newValue;
    1523                            break;
    1524                    case 14:
    1525                            mSidCached |= 0x800;
    1526                            mPhoneOffice=  newValue;
    1527                            break;
    1528                    case 15:
    1529                            mSidCached |= 0x1000;
    1530                            mPhoneMobile=  newValue;
    1531                            break;
    1532                    case 16:
    1533                            mSidCached |= 0x2000;
    1534                            mEmails=  newValue;
    1535                            break;
    1536                    case 17:
    1537                            mSidCached |= 0x4000;
    1538                            mHomepage=  newValue;
    1539                            break;
    1540                    case 18:
    1541                            mSidCached |= 0x8000;
    1542                            mAbout=  newValue;
    1543                            break;
    1544                    case 26:
    1545                            mSidCached |= 0x20000;
    1546                            mMoodText=  newValue;
    1547                            break;
    1548                    case 205:
    1549                            mSidCached |= 0x40000;
    1550                            mRichMoodText=  newValue;                       break;
    1551                    case 29:
    1552                            mSidCached |= 0x800000;
    1553                            mIpCountry=  newValue;
    1554                            break;
    1555                    case 20:
    1556                            mSidCached |= 0x4000000;
    1557                            mReceivedAuthRequest=  newValue;
    1558                            break;
    1559                    case 21:
    1560                            mSidCached |= 0x40000000;
    1561                            mDisplayName=  newValue;
    1562                            break;
    1563                    case 33:
    1564                            mSidExtraCached[0] |= 0x2;
    1565                            mGivenDisplayName=  newValue;
    1566                            break;
    1567                    case 180:
    1568                            mSidExtraCached[0] |= 0x4;
    1569                            mAssignedComment=  newValue;
    1570                            break;
    1571                    case 184:
    1572                            mSidExtraCached[0] |= 0x20;
    1573                            mAssignedPhone1=  newValue;
    1574                            break;
    1575                    case 185:
    1576                            mSidExtraCached[0] |= 0x40;
    1577                            mAssignedPhone1Label=  newValue;
    1578                            break;
    1579                    case 186:
    1580                            mSidExtraCached[0] |= 0x80;
    1581                            mAssignedPhone2=  newValue;
    1582                            break;
    1583                    case 187:
    1584                            mSidExtraCached[0] |= 0x100;
    1585                            mAssignedPhone2Label=  newValue;
    1586                            break;
    1587                    case 188:
    1588                            mSidExtraCached[0] |= 0x200;
    1589                            mAssignedPhone3=  newValue;
    1590                            break;
    1591                    case 189:
    1592                            mSidExtraCached[0] |= 0x400;
    1593                            mAssignedPhone3Label=  newValue;
    1594                            break;
    1595                    }
    1596            }
    1597            public void sidSetProperty(final PropertyEnumConverting prop, final int newValue) {
    1598                    final int propId = prop.getId();
    1599                    switch(propId) {
    1600                    case 202:
    1601                            mSidCached |= 0x1;
    1602                            mType= Type.get(newValue);
    1603                            break;
    1604                    case 7:
    1605                            mSidCached |= 0x10;
    1606                            mBirthday=  newValue;
    1607                            break;
    1608                    case 8:
    1609                            mSidCached |= 0x20;
    1610                            mGender=  newValue;
    1611                            break;
    1612                    case 27:
    1613                            mSidCached |= 0x80000;
    1614                            mTimezone=  newValue;
    1615                            break;
    1616                    case 19:
    1617                            mSidCached |= 0x200000;
    1618                            mProfileTimestamp=  newValue;
    1619                            break;
    1620                    case 28:
    1621                            mSidCached |= 0x400000;
    1622                            mNrofAuthedBuddies=  newValue;
    1623                            break;
    1624                    case 182:
    1625                            mSidCached |= 0x1000000;
    1626                            mAvatarTimestamp=  newValue;
    1627                            break;
    1628                    case 183:
    1629                            mSidCached |= 0x2000000;
    1630                            mMoodTimestamp=  newValue;
    1631                            break;
    1632                    case 25:
    1633                            mSidCached |= 0x8000000;
    1634                            mAuthRequestTimestamp=  newValue;
    1635                            break;
    1636                    case 35:
    1637                            mSidCached |= 0x10000000;
    1638                            mLastOnlineTimestamp=  newValue;
    1639                            break;
    1640                    case 34:
    1641                            mSidCached |= 0x20000000;
    1642                            mAvailability= Availability.get(newValue);
    1643                            break;
    1644                    case 22:
    1645                            mSidCached |= 0x80000000;
    1646                            mRefreshing= newValue != 0;
    1647                            break;
    1648                    case 23:
    1649                            mSidExtraCached[0] |= 0x1;
    1650                            mGivenAuthLevel= AuthLevel.get(newValue);
    1651                            break;
    1652                    case 39:
    1653                            mSidExtraCached[0] |= 0x8;
    1654                            mLastUsedTimestamp=  newValue;
    1655                            break;
    1656                    case 41:
    1657                            mSidExtraCached[0] |= 0x10;
    1658                            mAuthRequestCount=  newValue;
    1659                            break;
    1660                    case 42:
    1661                            mSidExtraCached[0] |= 0x800;
    1662                            mPopularityOrd=  newValue;
    1663                            break;
    1664                    }
    1665            }
    1666            public void sidSetProperty(final PropertyEnumConverting prop, final byte[] newValue) {
    1667                    final int propId = prop.getId();
    1668                    switch(propId) {
    1669                    case 37:
    1670                            mSidCached |= 0x10000;
    1671                            mAvatarImage=  newValue;
    1672                            break;
    1673                    case 36:
    1674                            mSidCached |= 0x100000;
    1675                            mCapabilities=  newValue;
    1676                            break;
    1677                    }
    1678            }
    1679            public Type         mType;
    1680            public String       mSkypeName;
    1681            public String       mPstnNumber;
    1682            public String       mFullName;
    1683            public int          mBirthday;
    1684            public int          mGender;
    1685            public String       mLanguages;
    1686            public String       mCountry;
    1687            public String       mProvince;
    1688            public String       mCity;
    1689            public String       mPhoneHome;
    1690            public String       mPhoneOffice;
    1691            public String       mPhoneMobile;
    1692            public String       mEmails;
    1693            public String       mHomepage;
    1694            public String       mAbout;
    1695            public byte[]       mAvatarImage;
    1696            public String       mMoodText;
    1697            public String       mRichMoodText;
    1698            public int          mTimezone;
    1699            public byte[]       mCapabilities;
    1700            public int          mProfileTimestamp;
    1701            public int          mNrofAuthedBuddies;
    1702            public String       mIpCountry;
    1703            public int          mAvatarTimestamp;
    1704            public int          mMoodTimestamp;
    1705            public String       mReceivedAuthRequest;
    1706            public int          mAuthRequestTimestamp;
    1707            public int          mLastOnlineTimestamp;
    1708            public Availability mAvailability;
    1709            public String       mDisplayName;
    1710            public boolean      mRefreshing;
    1711            public AuthLevel    mGivenAuthLevel;
    1712            public String       mGivenDisplayName;
    1713            public String       mAssignedComment;
    1714            public int          mLastUsedTimestamp;
    1715            public int          mAuthRequestCount;
    1716            public String       mAssignedPhone1;
    1717            public String       mAssignedPhone1Label;
    1718            public String       mAssignedPhone2;
    1719            public String       mAssignedPhone2Label;
    1720            public String       mAssignedPhone3;
    1721            public String       mAssignedPhone3Label;
    1722            public int          mPopularityOrd;
    1723            /***
    1724             * invalidateCache: the next time the property is get, it will be querried to the runtime, meanwhile it can be discarded.
    1725             * This allows fine grained cache management. Note that this doesn't delete the property, you still have to set it to null
    1726             * to get a chance having this behavior. The rationale if that the generated properties being public, you can directly assign it to null
    1727             * whilst a generated invalidateCache would require switching on the values to do so.
    1728             * Contact o; o.invalidate(Contact.Property.P_MY_PROP); o.mMyProp = null;
    1729             * @param property the property to be invalidated
    1730             */
    1731            public void invalidateCache(final PropertyEnumConverting property) {
    1732                    int idx   = property.getIdx();
    1733                    if (idx-- > 0) {
    1734                            int word = idx / 32;
    1735                            if (word-- == 0) mSidCached = ~(1<<(idx%32));
    1736             else mSidExtraCached[word] &=~(1<<(idx%32));
    1737                    }
    1738            }
    1739
    1740            protected boolean isCached(final PropertyEnumConverting property) {
    1741                    int idx = property.getIdx();
    1742                    if (idx-- > 0) {
    1743                            int word = idx / 32;
    1744                            if (word-- == 0) return (mSidCached & ~(1<<(idx%32))) != 0;
    1745                            else return (mSidExtraCached[word] & ~(1<<(idx%32))) != 0;
    1746                    }
    1747                    return false;
    1748            }
    1749
    1750            protected boolean hasCached() {
    1751                    if (mSidCached != 0) return true;
    1752                    for (int i = 0, e = mSidExtraCached.length; i < e; i++)
    1753                            if (mSidExtraCached[i] != 0) return true;
    1754                    return false;
    1755            }
    1756            private int[] mSidExtraCached = new int[1];
    1757            public int moduleId() {
    1758                    return 2;
    1759            }
    1760
    1761            public Contact(final int oid, final SidRoot root) {
    1762                    super(oid, root, 44);
    1763            }
    1764    }