    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.Participant;
    013    import com.skype.api.Skype;
    014    import com.skype.ipc.SidGetResponding;
    015
    016    /** The Conversation class encapsulates all types of communication possible with Skype client. Instant messaging, calls, video calls, file transfers, SMS, screen sharing - all take place within the context of a Conversation. Contacts are represented in Conversation as Participant objects. This also applies to contacts of PSTN type. All events in a conversation are represented as Message objects.   */
    017    public final class Conversation extends SidObject {
    018            public enum Type implements EnumConverting {
    019                    /** 1:1 conversations, there is a one dialog per identity */
    020                    DIALOG                 (1),
    021                    /** equivalent of a multichat */
    022                    CONFERENCE             (2),
    023                    /** a conference that has been terminated (disbanded chat) */
    024                    TERMINATED_CONFERENCE  (3),
    025                    /** voice-only conference, when host is using a legacy non-conversation client */
    026                    LEGACY_VOICE_CONFERENCE(4),
    027                    /** chat used for legacy shared groups, can be ignored */
    028                    LEGACY_SHAREDGROUP     (5);
    029                    private final int key;
    030                    Type(int key) {
    031                            this.key = key;
    032                    };
    033                    public int getId()   { return key; }
    034                    public EnumConverting getDefault() { return DIALOG; }
    035                    public EnumConverting convert(int from) { return Type.get(from); }
    036                    public EnumConverting[] getArray(final int size) { return new Type[size]; }
    037                    public static Type get(int from) {
    038                            switch (from) {
    039                            case 1: return DIALOG;
    040                            case 2: return CONFERENCE;
    041                            case 3: return TERMINATED_CONFERENCE;
    042                            case 4: return LEGACY_VOICE_CONFERENCE;
    043                            case 5: return LEGACY_SHAREDGROUP;
    044                            }
    045                            return DIALOG;
    046                    }
    047                    public static final int DIALOG_VALUE                  = 1;
    048                    public static final int CONFERENCE_VALUE              = 2;
    049                    public static final int TERMINATED_CONFERENCE_VALUE   = 3;
    050                    public static final int LEGACY_VOICE_CONFERENCE_VALUE = 4;
    051                    public static final int LEGACY_SHAREDGROUP_VALUE      = 5;
    052            }
    053            public enum MyStatus implements EnumConverting {
    054                    /** connecting to conference */
    055                    CONNECTING          (1),
    056                    RETRY_CONNECTING    (2),
    057                    /** unused */
    058                    DOWNLOADING_MESSAGES(3),
    059                    /** conference is full for now, being queued */
    060                    QUEUED_TO_ENTER     (4),
    061                    /** I'm applying to join the conference */
    062                    APPLICANT           (5),
    063                    /** My application to join the conference was denied */
    064                    APPLICATION_DENIED  (6),
    065                    /** The password I provided is incorrect */
    066                    INVALID_ACCESS_TOKEN(7),
    067                    /** I'm part of the conference, I can participate */
    068                    CONSUMER            (8),
    069                    /** I was kicked from the conference */
    070                    RETIRED_FORCEFULLY  (9),
    071                    /** I left the conference */
    072                    RETIRED_VOLUNTARILY (10);
    073                    private final int key;
    074                    MyStatus(int key) {
    075                            this.key = key;
    076                    };
    077                    public int getId()   { return key; }
    078                    public EnumConverting getDefault() { return CONNECTING; }
    079                    public EnumConverting convert(int from) { return MyStatus.get(from); }
    080                    public EnumConverting[] getArray(final int size) { return new MyStatus[size]; }
    081                    public static MyStatus get(int from) {
    082                            switch (from) {
    083                            case  1: return CONNECTING;
    084                            case  2: return RETRY_CONNECTING;
    085                            case  3: return DOWNLOADING_MESSAGES;
    086                            case  4: return QUEUED_TO_ENTER;
    087                            case  5: return APPLICANT;
    088                            case  6: return APPLICATION_DENIED;
    089                            case  7: return INVALID_ACCESS_TOKEN;
    090                            case  8: return CONSUMER;
    091                            case  9: return RETIRED_FORCEFULLY;
    092                            case 10: return RETIRED_VOLUNTARILY;
    093                            }
    094                            return CONNECTING;
    095                    }
    096                    public static final int CONNECTING_VALUE           =  1;
    097                    public static final int RETRY_CONNECTING_VALUE     =  2;
    098                    public static final int DOWNLOADING_MESSAGES_VALUE =  3;
    099                    public static final int QUEUED_TO_ENTER_VALUE      =  4;
    100                    public static final int APPLICANT_VALUE            =  5;
    101                    public static final int APPLICATION_DENIED_VALUE   =  6;
    102                    public static final int INVALID_ACCESS_TOKEN_VALUE =  7;
    103                    public static final int CONSUMER_VALUE             =  8;
    104                    public static final int RETIRED_FORCEFULLY_VALUE   =  9;
    105                    public static final int RETIRED_VOLUNTARILY_VALUE  = 10;
    106            }
    107            public enum LocalLiveStatus implements EnumConverting {
    108                    /** there isn't a live session */
    109                    NONE                   (0),
    110                    /** trying to start or join a live session */
    111                    STARTING               (1),
    112                    /** there is a live session ringing */
    113                    RINGING_FOR_ME         (2),
    114                    /** the conference is live for me */
    115                    IM_LIVE                (3),
    116                    /** I put the live session on hold */
    117                    ON_HOLD_LOCALLY        (5),
    118                    /** the live session was put on hold by someone else */
    119                    ON_HOLD_REMOTELY       (6),
    120                    /** there is a live session on-going, I'm not participating but I could join */
    121                    OTHERS_ARE_LIVE        (7),
    122                    /** there is a live session on-going without me, but I can't join because it's full */
    123                    OTHERS_ARE_LIVE_FULL   (11),
    124                    /** playing a voicemail (dialog only) */
    125                    PLAYING_VOICE_MESSAGE  (8),
    126                    /** recording a voicemail (dialog only) */
    127                    RECORDING_VOICE_MESSAGE(9),
    128                    /** a live session just finished, we stay in this state for RECENTLY_LIVE_TIMEOUT setup key */
    129                    RECENTLY_LIVE          (10),
    130                    /** call is being transferred */
    131                    TRANSFERRING           (12);
    132                    private final int key;
    133                    LocalLiveStatus(int key) {
    134                            this.key = key;
    135                    };
    136                    public int getId()   { return key; }
    137                    public EnumConverting getDefault() { return NONE; }
    138                    public EnumConverting convert(int from) { return LocalLiveStatus.get(from); }
    139                    public EnumConverting[] getArray(final int size) { return new LocalLiveStatus[size]; }
    140                    public static LocalLiveStatus get(int from) {
    141                            switch (from) {
    142                            case  0: return NONE;
    143                            case  1: return STARTING;
    144                            case  2: return RINGING_FOR_ME;
    145                            case  3: return IM_LIVE;
    146                            case  5: return ON_HOLD_LOCALLY;
    147                            case  6: return ON_HOLD_REMOTELY;
    148                            case  7: return OTHERS_ARE_LIVE;
    149                            case 11: return OTHERS_ARE_LIVE_FULL;
    150                            case  8: return PLAYING_VOICE_MESSAGE;
    151                            case  9: return RECORDING_VOICE_MESSAGE;
    152                            case 10: return RECENTLY_LIVE;
    153                            case 12: return TRANSFERRING;
    154                            }
    155                            return NONE;
    156                    }
    157                    public static final int NONE_VALUE                    =  0;
    158                    public static final int STARTING_VALUE                =  1;
    159                    public static final int RINGING_FOR_ME_VALUE          =  2;
    160                    public static final int IM_LIVE_VALUE                 =  3;
    161                    public static final int ON_HOLD_LOCALLY_VALUE         =  5;
    162                    public static final int ON_HOLD_REMOTELY_VALUE        =  6;
    163                    public static final int OTHERS_ARE_LIVE_VALUE         =  7;
    164                    public static final int OTHERS_ARE_LIVE_FULL_VALUE    = 11;
    165                    public static final int PLAYING_VOICE_MESSAGE_VALUE   =  8;
    166                    public static final int RECORDING_VOICE_MESSAGE_VALUE =  9;
    167                    public static final int RECENTLY_LIVE_VALUE           = 10;
    168                    public static final int TRANSFERRING_VALUE            = 12;
    169            }
    170            /** values for opt_admin_only_activities property */
    171            public enum AllowedActivity implements EnumConverting {
    172                    /** allowed to set the CONVERSATION_META properties */
    173                    SET_META       (1),
    174                    /** allowed to add participants to the conference */
    175                    ADD_CONSUMERS  (2),
    176                    /** allowed to speak, but not write */
    177                    SPEAK          (4),
    178                    /** allowed to speak and write */
    179                    SPEAK_AND_WRITE(8);
    180                    private final int key;
    181                    AllowedActivity(int key) {
    182                            this.key = key;
    183                    };
    184                    public int getId()   { return key; }
    185                    public EnumConverting getDefault() { return SET_META; }
    186                    public EnumConverting convert(int from) { return AllowedActivity.get(from); }
    187                    public EnumConverting[] getArray(final int size) { return new AllowedActivity[size]; }
    188                    public static AllowedActivity get(int from) {
    189                            switch (from) {
    190                            case 1: return SET_META;
    191                            case 2: return ADD_CONSUMERS;
    192                            case 4: return SPEAK;
    193                            case 8: return SPEAK_AND_WRITE;
    194                            }
    195                            return SET_META;
    196                    }
    197                    public static final int SET_META_VALUE        = 1;
    198                    public static final int ADD_CONSUMERS_VALUE   = 2;
    199                    public static final int SPEAK_VALUE           = 4;
    200                    public static final int SPEAK_AND_WRITE_VALUE = 8;
    201            }
    202            public enum ParticipantFilter implements EnumConverting {
    203                    /** All participants (may included some that are RETIRED or OUTLAW, but not all of them) */
    204                    ALL                     (0),
    205                    /** Participants that can receive messages, including myself */
    206                    CONSUMERS               (1),
    207                    /** Only people who are applying to join the conversation */
    208                    APPLICANTS              (2),
    209                    /** Consumers and applicants */
    210                    CONSUMERS_AND_APPLICANTS(3),
    211                    /** Myself */           MYSELF                  (4),
    212                    /** All consumers except myself */
    213                    OTHER_CONSUMERS         (5);
    214                    private final int key;
    215                    ParticipantFilter(int key) {
    216                            this.key = key;
    217                    };
    218                    public int getId()   { return key; }
    219                    public EnumConverting getDefault() { return ALL; }
    220                    public EnumConverting convert(int from) { return ParticipantFilter.get(from); }
    221                    public EnumConverting[] getArray(final int size) { return new ParticipantFilter[size]; }
    222                    public static ParticipantFilter get(int from) {
    223                            switch (from) {
    224                            case 0: return ALL;
    225                            case 1: return CONSUMERS;
    226                            case 2: return APPLICANTS;
    227                            case 3: return CONSUMERS_AND_APPLICANTS;
    228                            case 4: return MYSELF;
    229                            case 5: return OTHER_CONSUMERS;
    230                            }
    231                            return ALL;
    232                    }
    233                    public static final int ALL_VALUE                      = 0;
    234                    public static final int CONSUMERS_VALUE                = 1;
    235                    public static final int APPLICANTS_VALUE               = 2;
    236                    public static final int CONSUMERS_AND_APPLICANTS_VALUE = 3;
    237                    public static final int MYSELF_VALUE                   = 4;
    238                    public static final int OTHER_CONSUMERS_VALUE          = 5;
    239            }
    240            public enum ListType implements EnumConverting {
    241                    /** bookmarked or in_inbox or live or with_meta_info or activity in last 30 days */
    242                    ALL_CONVERSATIONS       (0),
    243                    /** only last 6 months conversations are kept there */
    244                    INBOX_CONVERSATIONS     (1),
    245                    /** is_bookmarked is set */
    246                    BOOKMARKED_CONVERSATIONS(2),
    247                    /** local_livestatus is different from NONE */
    248                    LIVE_CONVERSATIONS      (3),
    249                    /** all conversations, without any of the limits of ALL_CONVERSATIONS */
    250                    REALLY_ALL_CONVERSATIONS(5);
    251                    private final int key;
    252                    ListType(int key) {
    253                            this.key = key;
    254                    };
    255                    public int getId()   { return key; }
    256                    public EnumConverting getDefault() { return ALL_CONVERSATIONS; }
    257                    public EnumConverting convert(int from) { return ListType.get(from); }
    258                    public EnumConverting[] getArray(final int size) { return new ListType[size]; }
    259                    public static ListType get(int from) {
    260                            switch (from) {
    261                            case 0: return ALL_CONVERSATIONS;
    262                            case 1: return INBOX_CONVERSATIONS;
    263                            case 2: return BOOKMARKED_CONVERSATIONS;
    264                            case 3: return LIVE_CONVERSATIONS;
    265                            case 5: return REALLY_ALL_CONVERSATIONS;
    266                            }
    267                            return ALL_CONVERSATIONS;
    268                    }
    269                    public static final int ALL_CONVERSATIONS_VALUE        = 0;
    270                    public static final int INBOX_CONVERSATIONS_VALUE      = 1;
    271                    public static final int BOOKMARKED_CONVERSATIONS_VALUE = 2;
    272                    public static final int LIVE_CONVERSATIONS_VALUE       = 3;
    273                    public static final int REALLY_ALL_CONVERSATIONS_VALUE = 5;
    274            }
    275            private final static byte[] P_IDENTITY_req = {(byte) 90,(byte) 71,(byte) 204,(byte) 7,(byte) 93,(byte) 18};
    276            private final static byte[] P_TYPE_req = {(byte) 90,(byte) 71,(byte) 134,(byte) 7,(byte) 93,(byte) 18};
    277            private final static byte[] P_LIVE_HOST_req = {(byte) 90,(byte) 71,(byte) 150,(byte) 7,(byte) 93,(byte) 18};
    278            private final static byte[] P_LIVE_START_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 206,(byte) 7,(byte) 93,(byte) 18};
    279            private final static byte[] P_LIVE_IS_MUTED_req = {(byte) 90,(byte) 71,(byte) 228,(byte) 7,(byte) 93,(byte) 18};
    280            private final static byte[] P_ALERT_STRING_req = {(byte) 90,(byte) 71,(byte) 152,(byte) 7,(byte) 93,(byte) 18};
    281            private final static byte[] P_IS_BOOKMARKED_req = {(byte) 90,(byte) 71,(byte) 153,(byte) 7,(byte) 93,(byte) 18};
    282            private final static byte[] P_GIVEN_DISPLAY_NAME_req = {(byte) 90,(byte) 71,(byte) 157,(byte) 7,(byte) 93,(byte) 18};
    283            private final static byte[] P_DISPLAY_NAME_req = {(byte) 90,(byte) 71,(byte) 156,(byte) 7,(byte) 93,(byte) 18};
    284            private final static byte[] P_LOCAL_LIVE_STATUS_req = {(byte) 90,(byte) 71,(byte) 159,(byte) 7,(byte) 93,(byte) 18};
    285            private final static byte[] P_INBOX_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 160,(byte) 7,(byte) 93,(byte) 18};
    286            private final static byte[] P_INBOX_MESSAGE_ID_req = {(byte) 90,(byte) 71,(byte) 205,(byte) 7,(byte) 93,(byte) 18};
    287            private final static byte[] P_UNCONSUMED_SUPPRESSED_MESSAGES_req = {(byte) 90,(byte) 71,(byte) 207,(byte) 7,(byte) 93,(byte) 18};
    288            private final static byte[] P_UNCONSUMED_NORMAL_MESSAGES_req = {(byte) 90,(byte) 71,(byte) 208,(byte) 7,(byte) 93,(byte) 18};
    289            private final static byte[] P_UNCONSUMED_ELEVATED_MESSAGES_req = {(byte) 90,(byte) 71,(byte) 209,(byte) 7,(byte) 93,(byte) 18};
    290            private final static byte[] P_UNCONSUMED_MESSAGES_VOICE_req = {(byte) 90,(byte) 71,(byte) 202,(byte) 7,(byte) 93,(byte) 18};
    291            private final static byte[] P_ACTIVE_VOICEMAIL_req = {(byte) 90,(byte) 71,(byte) 203,(byte) 7,(byte) 93,(byte) 18};
    292            private final static byte[] P_CONSUMPTION_HORIZON_req = {(byte) 90,(byte) 71,(byte) 211,(byte) 7,(byte) 93,(byte) 18};
    293            private final static byte[] P_LAST_ACTIVITY_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 213,(byte) 7,(byte) 93,(byte) 18};
    294            private final static byte[] P_SPAWNED_FROM_CONVO_ID_req = {(byte) 90,(byte) 71,(byte) 147,(byte) 7,(byte) 93,(byte) 18};
    295            private final static byte[] P_CREATOR_req = {(byte) 90,(byte) 71,(byte) 135,(byte) 7,(byte) 93,(byte) 18};
    296            private final static byte[] P_CREATION_TIMESTAMP_req = {(byte) 90,(byte) 71,(byte) 136,(byte) 7,(byte) 93,(byte) 18};
    297            private final static byte[] P_MY_STATUS_req = {(byte) 90,(byte) 71,(byte) 151,(byte) 7,(byte) 93,(byte) 18};
    298            private final static byte[] P_OPT_JOINING_ENABLED_req = {(byte) 90,(byte) 71,(byte) 154,(byte) 7,(byte) 93,(byte) 18};
    299            private final static byte[] P_OPT_ENTRY_LEVEL_RANK_req = {(byte) 90,(byte) 71,(byte) 138,(byte) 7,(byte) 93,(byte) 18};
    300            private final static byte[] P_OPT_DISCLOSE_HISTORY_req = {(byte) 90,(byte) 71,(byte) 139,(byte) 7,(byte) 93,(byte) 18};
    301            private final static byte[] P_OPT_ADMIN_ONLY_ACTIVITIES_req = {(byte) 90,(byte) 71,(byte) 141,(byte) 7,(byte) 93,(byte) 18};
    302            private final static byte[] P_PASSWORD_HINT_req = {(byte) 90,(byte) 71,(byte) 212,(byte) 7,(byte) 93,(byte) 18};
    303            private final static byte[] P_META_NAME_req = {(byte) 90,(byte) 71,(byte) 142,(byte) 7,(byte) 93,(byte) 18};
    304            private final static byte[] P_META_TOPIC_req = {(byte) 90,(byte) 71,(byte) 143,(byte) 7,(byte) 93,(byte) 18};
    305            private final static byte[] P_META_GUIDELINES_req = {(byte) 90,(byte) 71,(byte) 145,(byte) 7,(byte) 93,(byte) 18};
    306            private final static byte[] P_META_PICTURE_req = {(byte) 90,(byte) 71,(byte) 146,(byte) 7,(byte) 93,(byte) 18};
    307            /** Properties of the Conversation class */
    308            public enum Property implements PropertyEnumConverting {
    309                    P_UNKNOWN                       (0,0,null,0,null),
    310                    P_IDENTITY                      (972, 1, P_IDENTITY_req, 0, null),
    311                    P_TYPE                          (902, 2, P_TYPE_req, 0, Type.get(0)),
    312                    P_LIVE_HOST                     (918, 3, P_LIVE_HOST_req, 0, null),
    313                    P_LIVE_START_TIMESTAMP          (974, 4, P_LIVE_START_TIMESTAMP_req, 0, null),
    314                    P_LIVE_IS_MUTED                 (996, 5, P_LIVE_IS_MUTED_req, 0, null),
    315                    P_ALERT_STRING                  (920, 6, P_ALERT_STRING_req, 0, null),
    316                    P_IS_BOOKMARKED                 (921, 7, P_IS_BOOKMARKED_req, 0, null),
    317                    P_GIVEN_DISPLAY_NAME            (925, 8, P_GIVEN_DISPLAY_NAME_req, 0, null),
    318                    P_DISPLAY_NAME                  (924, 9, P_DISPLAY_NAME_req, 0, null),
    319                    P_LOCAL_LIVE_STATUS             (927, 10, P_LOCAL_LIVE_STATUS_req, 0, LocalLiveStatus.get(0)),
    320                    P_INBOX_TIMESTAMP               (928, 11, P_INBOX_TIMESTAMP_req, 0, null),
    321                    P_INBOX_MESSAGE_ID              (973, 12, P_INBOX_MESSAGE_ID_req, 9, null),
    322                    P_UNCONSUMED_SUPPRESSED_MESSAGES(975, 13, P_UNCONSUMED_SUPPRESSED_MESSAGES_req, 0, null),
    323                    P_UNCONSUMED_NORMAL_MESSAGES    (976, 14, P_UNCONSUMED_NORMAL_MESSAGES_req, 0, null),
    324                    P_UNCONSUMED_ELEVATED_MESSAGES  (977, 15, P_UNCONSUMED_ELEVATED_MESSAGES_req, 0, null),
    325                    P_UNCONSUMED_MESSAGES_VOICE     (970, 16, P_UNCONSUMED_MESSAGES_VOICE_req, 0, null),
    326                    P_ACTIVE_VOICEMAIL              (971, 17, P_ACTIVE_VOICEMAIL_req, 7, null),
    327                    P_CONSUMPTION_HORIZON           (979, 18, P_CONSUMPTION_HORIZON_req, 0, null),
    328                    P_LAST_ACTIVITY_TIMESTAMP       (981, 19, P_LAST_ACTIVITY_TIMESTAMP_req, 0, null),
    329                    P_SPAWNED_FROM_CONVO_ID         (915, 20, P_SPAWNED_FROM_CONVO_ID_req, 18, null),
    330                    P_CREATOR                       (903, 21, P_CREATOR_req, 0, null),
    331                    P_CREATION_TIMESTAMP            (904, 22, P_CREATION_TIMESTAMP_req, 0, null),           P_MY_STATUS                     (919, 23, P_MY_STATUS_req, 0, MyStatus.get(0)),
    332                    P_OPT_JOINING_ENABLED           (922, 24, P_OPT_JOINING_ENABLED_req, 0, null),
    333                    P_OPT_ENTRY_LEVEL_RANK          (906, 25, P_OPT_ENTRY_LEVEL_RANK_req, 0, Participant.Rank.get(0)),
    334                    P_OPT_DISCLOSE_HISTORY          (907, 26, P_OPT_DISCLOSE_HISTORY_req, 0, null),
    335                    P_OPT_ADMIN_ONLY_ACTIVITIES     (909, 27, P_OPT_ADMIN_ONLY_ACTIVITIES_req, 0, null),
    336                    P_PASSWORD_HINT                 (980, 28, P_PASSWORD_HINT_req, 0, null),
    337                    P_META_NAME                     (910, 29, P_META_NAME_req, 0, null),
    338                    P_META_TOPIC                    (911, 30, P_META_TOPIC_req, 0, null),
    339                    P_META_GUIDELINES               (913, 31, P_META_GUIDELINES_req, 0, null),
    340                    P_META_PICTURE                  (914, 32, P_META_PICTURE_req, 0, null);
    341                    private final int    key;
    342                    private final int    idx;
    343                    private final byte[] req;
    344                    private final int    mod;
    345                    private final EnumConverting enumConverter;
    346                    Property(int key, int idx, byte[] req, int mod, EnumConverting converter) {
    347                            this.key = key;
    348                            this.idx = idx;
    349                            this.req = req;
    350                            this.mod = mod;
    351                            this.enumConverter = converter;
    352                    };
    353                    public boolean  isCached()    { return idx > 0;   }
    354                    public int      getIdx()      { return idx;       }
    355                    public int      getId()       { return key;       }
    356                    public byte[]   getRequest()  { return req;       }
    357                    public EnumConverting getDefault()  { return P_UNKNOWN; }
    358                    public int      getModuleId() { return mod;       }
    359                    public EnumConverting getEnumConverter()    { return enumConverter;   }
    360                    public EnumConverting convert(final int from) { return Property.get(from); }
    361                    public EnumConverting[] getArray(final int size) { return new Property[size]; }
    362                    public static Property get(final int from) {
    363                            switch (from) {
    364                            case 972: return P_IDENTITY;
    365                            case 902: return P_TYPE;
    366                            case 918: return P_LIVE_HOST;
    367                            case 974: return P_LIVE_START_TIMESTAMP;
    368                            case 996: return P_LIVE_IS_MUTED;
    369                            case 920: return P_ALERT_STRING;
    370                            case 921: return P_IS_BOOKMARKED;
    371                            case 925: return P_GIVEN_DISPLAY_NAME;
    372                            case 924: return P_DISPLAY_NAME;
    373                            case 927: return P_LOCAL_LIVE_STATUS;
    374                            case 928: return P_INBOX_TIMESTAMP;
    375                            case 973: return P_INBOX_MESSAGE_ID;
    376                            case 975: return P_UNCONSUMED_SUPPRESSED_MESSAGES;
    377                            case 976: return P_UNCONSUMED_NORMAL_MESSAGES;
    378                            case 977: return P_UNCONSUMED_ELEVATED_MESSAGES;
    379                            case 970: return P_UNCONSUMED_MESSAGES_VOICE;
    380                            case 971: return P_ACTIVE_VOICEMAIL;
    381                            case 979: return P_CONSUMPTION_HORIZON;
    382                            case 981: return P_LAST_ACTIVITY_TIMESTAMP;
    383                            case 915: return P_SPAWNED_FROM_CONVO_ID;
    384                            case 903: return P_CREATOR;
    385                            case 904: return P_CREATION_TIMESTAMP;
    386                            case 919: return P_MY_STATUS;
    387                            case 922: return P_OPT_JOINING_ENABLED;
    388                            case 906: return P_OPT_ENTRY_LEVEL_RANK;
    389                            case 907: return P_OPT_DISCLOSE_HISTORY;
    390                            case 909: return P_OPT_ADMIN_ONLY_ACTIVITIES;
    391                            case 980: return P_PASSWORD_HINT;
    392                            case 910: return P_META_NAME;
    393                            case 911: return P_META_TOPIC;
    394                            case 913: return P_META_GUIDELINES;
    395                            case 914: return P_META_PICTURE;
    396                            }
    397                            return P_UNKNOWN;
    398                    }
    399                    public static final int P_IDENTITY_VALUE                       = 972;
    400                    public static final int P_TYPE_VALUE                           = 902;
    401                    public static final int P_LIVE_HOST_VALUE                      = 918;
    402                    public static final int P_LIVE_START_TIMESTAMP_VALUE           = 974;
    403                    public static final int P_LIVE_IS_MUTED_VALUE                  = 996;
    404                    public static final int P_ALERT_STRING_VALUE                   = 920;
    405                    public static final int P_IS_BOOKMARKED_VALUE                  = 921;
    406                    public static final int P_GIVEN_DISPLAY_NAME_VALUE             = 925;
    407                    public static final int P_DISPLAY_NAME_VALUE                   = 924;
    408                    public static final int P_LOCAL_LIVE_STATUS_VALUE              = 927;
    409                    public static final int P_INBOX_TIMESTAMP_VALUE                = 928;
    410                    public static final int P_INBOX_MESSAGE_ID_VALUE               = 973;
    411                    public static final int P_UNCONSUMED_SUPPRESSED_MESSAGES_VALUE = 975;
    412                    public static final int P_UNCONSUMED_NORMAL_MESSAGES_VALUE     = 976;
    413                    public static final int P_UNCONSUMED_ELEVATED_MESSAGES_VALUE   = 977;
    414                    public static final int P_UNCONSUMED_MESSAGES_VOICE_VALUE      = 970;
    415                    public static final int P_ACTIVE_VOICEMAIL_VALUE               = 971;
    416                    public static final int P_CONSUMPTION_HORIZON_VALUE            = 979;
    417                    public static final int P_LAST_ACTIVITY_TIMESTAMP_VALUE        = 981;
    418                    public static final int P_SPAWNED_FROM_CONVO_ID_VALUE          = 915;
    419                    public static final int P_CREATOR_VALUE                        = 903;
    420                    public static final int P_CREATION_TIMESTAMP_VALUE             = 904;
    421                    public static final int P_MY_STATUS_VALUE                      = 919;
    422                    public static final int P_OPT_JOINING_ENABLED_VALUE            = 922;
    423                    public static final int P_OPT_ENTRY_LEVEL_RANK_VALUE           = 906;
    424                    public static final int P_OPT_DISCLOSE_HISTORY_VALUE           = 907;
    425                    public static final int P_OPT_ADMIN_ONLY_ACTIVITIES_VALUE      = 909;
    426                    public static final int P_PASSWORD_HINT_VALUE                  = 980;
    427                    public static final int P_META_NAME_VALUE                      = 910;
    428                    public static final int P_META_TOPIC_VALUE                     = 911;
    429                    public static final int P_META_GUIDELINES_VALUE                = 913;
    430                    public static final int P_META_PICTURE_VALUE                   = 914;
    431                    public static final Property[] mget_info_mreq = { P_DISPLAY_NAME, P_UNCONSUMED_NORMAL_MESSAGES, P_INBOX_TIMESTAMP };
    432            }
    433            /** Setupkey SETUPKEY_ENABLE_BIRTHDAY_NOTIFICATION type:int default value:"1" <br>Enables/disables birthday notification messages. <br> - 0 - disable;  <br> - 1 - enable; <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    434            public static final String ENABLE_BIRTHDAY_NOTIFICATION = "Lib/Conversation/EnableBirthday";
    435
    436            /** Setupkey SETUPKEY_INBOX_UPDATE_TIMEOUT type:int  <br>Timeout in seconds, how old the Conversation.P_INBOX_TIMESTAMP has to be for it to be re-sorted in the inbox. <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    437            public static final String INBOX_UPDATE_TIMEOUT = "Lib/Conversation/InboxUpdateTimeout";
    438
    439            /** Setupkey SETUPKEY_RECENTLY_LIVE_TIMEOUT type:int default value:"20" <br>The number of seconds a formerly live conversation will remain the Conversation.LIVE_CONVERSATIONS filter. Note that while the conversation remains in Conversation.LIVE_CONVERSATIONS filter, Skype.OnConversationListChange events will not fire if there is another call coming up within the same conversation. Seeting this key to 0 will cause conversations to exit the Conversation.LIVE_CONVERSATIONS list immediately, after live state drops. <br><br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    440            public static final String RECENTLY_LIVE_TIMEOUT = "Lib/Conversation/RecentlyLiveTimeout";
    441
    442            /** Setupkey SETUPKEY_DISABLE_CHAT type:int  Disables chat (for voice only clients). <br>This setup key is machine-specific and affects all local accounts. <br> */
    443            public static final String DISABLE_CHAT = "Lib/Chat/DisableChat";
    444
    445            /** Setupkey SETUPKEY_DISABLE_CHAT_HISTORY type:int  <br>Disables storage of chat history. <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    446            public static final String DISABLE_CHAT_HISTORY = "Lib/Message/DisableHistory";
    447
    448            /** Setupkey SETUPKEY_CHAT_HISTORY_DAYS type:int  <br>Time limit for keeping local chat message history. <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    449            public static final String CHAT_HISTORY_DAYS = "Lib/Chat/HistoryDays";
    450
    451            /** Setupkey SETUPKEY_CHATDB_LIMIT_KB type:int default value:"0" Use this key to limit the size of the chat db. Value is in KB. By default there is no limit. A minimum of 16 MB is recommended. */
    452            public static final String CHATDB_LIMIT_KB = "Lib/Chat/ChatDBLimitKb";
    453
    454            /** Setupkey SETUPKEY_DISABLE_CHAT_ACTIVITY_INDICATION type:int  <br>Enables/disables transmitting typing indicator signals to othe participants of conversations. <br> - 0 - disable;  <br> - 1 - enable; <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */     public static final String DISABLE_CHAT_ACTIVITY_INDICATION = "Lib/Chat/DisableActivityIndication";
    455
    456            /** Setupkey SETUPKEY_CALL_NOANSWER_TIMEOUT type:int default value:"15" <br>Timeout in seconds after which the incoming live session will stop ringing (and if possible, proceed to voicemail or call forward). <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    457            public static final String CALL_NOANSWER_TIMEOUT = "Lib/Call/NoAnswerTimeout";
    458
    459            /** Setupkey SETUPKEY_CALL_SEND_TO_VM type:int  <br>Autoforwarding of incoming calls to voicemail. <br> - 0 - off <br> - 1 - on <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    460            public static final String CALL_SEND_TO_VM = "Lib/Call/SendToVM";
    461
    462            /** Setupkey SETUPKEY_CALL_APPLY_CF type:int  <br>Enables/disables call forwarding. <br> - 0 - disable;  <br> - 1 - enable; <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    463            public static final String CALL_APPLY_CF = "Lib/Call/ApplyCF";
    464
    465            /** Setupkey SETUPKEY_CALL_EMERGENCY_COUNTRY type:string  <br>Country code for emergency calls <br>This is account-specific setup key. It can only be used while an account is logged in. <br> */
    466            public static final String CALL_EMERGENCY_COUNTRY = "Lib/Call/EmergencyCountry";
    467
    468            private final static byte[] setOption_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 1};
    469            /** Setter method for Conversation option properties. Option properties are all Conversation properties starting with OPT_ prefix.  * @param propKey Conversation property key, for example: Conversation.OPT_JOINING_ENABLED
    470             * @param value New value for the option property.
    471             */
    472            public void setOption(int propKey, int value) {
    473                    try {
    474                            sidDoRequest(setOption_req)
    475                            .addEnumParm(1, propKey)
    476                            .addUintParm(2, value)
    477                            .endOneWay();
    478                    } catch(IOException e) {
    479                            mSidRoot.sidOnFatalError(e);
    480                    }
    481            }
    482            private final static byte[] setTopic_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 2};
    483            /** Setter for Conversation class META_TOPIC. This topic will be set for remote participants as well.  * @param topic New conversation topic.
    484             * @param isXml Notifies remote UIs that the new topic contains xml tags.
    485             */
    486            public void setTopic(String topic, boolean isXml) {
    487                    try {
    488                            sidDoRequest(setTopic_req)
    489                            .addStringParm(1, topic)
    490                            .addBoolParm(2, isXml)
    491                            .endOneWay();
    492                    } catch(IOException e) {
    493                            mSidRoot.sidOnFatalError(e);
    494                    }
    495            }
    496            private final static byte[] setGuidelines_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 3};
    497            /** Setter for Conversation META_GUIDELINES. This property will be visible to remote participants of the conversation.  * @param guidelines New value for the META_GUIDELINES property.
    498             * @param isXml Set true to notify remote UIs that the new guideline contains XML tags.
    499             */
    500            public void setGuidelines(String guidelines, boolean isXml) {
    501                    try {
    502                            sidDoRequest(setGuidelines_req)
    503                            .addStringParm(1, guidelines)
    504                            .addBoolParm(2, isXml)
    505                            .endOneWay();
    506                    } catch(IOException e) {
    507                            mSidRoot.sidOnFatalError(e);
    508                    }
    509            }
    510            private final static byte[] setPicture_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 4};
    511            /** Sets the conversation's avatar to the specified JPEG image, which is propagated to both local and remote participants. Before calling this method, you should use Skype.ValidateAvatar to verify that jpeg references a valid JPEG image.  * @param jpeg Conversation avatar binary.
    512             */
    513            public void setPicture(byte[] jpeg) {
    514                    try {
    515                            sidDoRequest(setPicture_req)
    516                            .addBinaryParm(1, jpeg)
    517                            .endOneWay();
    518                    } catch(IOException e) {
    519                            mSidRoot.sidOnFatalError(e);
    520                    }
    521            }
    522            private final static byte[] spawnConference_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 6};
    523            /** When called from dialog conversation, this spawns a new conversation, with existing two dialog participants plus new contact identities given in the identitiesToAdd list. You do not need to add existing dialog participants to the string list. In fact, passing only the existing participants in the identities list will cause the method call to fail (return false), the same as if the list was empty. This method will also return false if the original conversation was not a dialog (contained more than two participants). Also note that this method always creates a new Conversation - even if a conversation with exactly the same participant list existed before.  * @param identitiesToAdd String list of additional participant identities. You do not need to add existing two participants from the original dialog to this list.
    524             * @return conference Returns the resulting conversation or 0 if the method call failed.
    525             */
    526            public Conversation spawnConference(String[] identitiesToAdd) {
    527                    try {
    528                            return (Conversation) sidDoRequest(spawnConference_req)
    529                            .addStringListParm(1, identitiesToAdd)
    530                            .endRequest().getObjectParm(1, 18, true);
    531                    } catch(IOException e) {
    532                            mSidRoot.sidOnFatalError(e);
    533                            return null
    534                    ;}
    535            }
    536            private final static byte[] addConsumers_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 7};
    537            /** Takes one or more Contact identities and creates corresponding Participant objects within the context of this Conversation, which must be of type CONFERENCE. If you have an existing dialog conversation, use SpawnConference instead.  * @param identities Contact identities to be added to the Conversation.
    538             */
    539            public void addConsumers(String[] identities) {
    540                    try {
    541                            sidDoRequest(addConsumers_req)
    542                            .addStringListParm(1, identities)
    543                            .endOneWay();
    544                    } catch(IOException e) {
    545                            mSidRoot.sidOnFatalError(e);
    546                    }
    547            }
    548            private final static byte[] assimilate_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 9};
    549            /** Merges two live conversations. For example, if the user already has a live conversation up - let's call it conversation A. Then a new incoming call occurs - another conversation obtains LOCAL_LIVESTATUS == Conversation.RINGING_FOR_ME, let's call it conversation B. The user wishes to pick up the new incoming call and add it to the existing one. For this you can first call B->JoinLiveSession and then merge two calls with A->Assimilate(B, A). The second argument will return the merged conversation. Note that there are actually three conversation objects involved: A (before merge), B and C (after the merge). Normally it would make sense to have the first conversation (A) as the second argument, so that it gets overwritten with the assimilation result.  * @param otherConversation The new conversation to be merged with the one already in live state.
    550             * @return conversation Returns a 3rd live conversation, result of merging two existing ones.
    551             */
    552            public Conversation assimilate(Conversation otherConversation) {
    553                    try {
    554                            return (Conversation) sidDoRequest(assimilate_req)
    555                            .addObjectParm(1, otherConversation)
    556                            .endRequest().getObjectParm(1, 18, true);
    557                    } catch(IOException e) {
    558                            mSidRoot.sidOnFatalError(e);
    559                            return null
    560                    ;}
    561            }
    562            private final static byte[] joinLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 10};
    563            /** starts, answers or joins a live session (first one to join becomes LIVE_HOST) * @param accessToken if starting a live session, allows to set a custom access token
    564             */
    565            public void joinLiveSession(String accessToken) {
    566                    try {
    567                            sidDoRequest(joinLiveSession_req)
    568                            .addStringParm(1, accessToken)
    569                            .endOneWay();
    570                    } catch(IOException e) {
    571                            mSidRoot.sidOnFatalError(e);
    572                    }
    573            }
    574            private final static byte[] ringOthers_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 36};
    575            /** This is an alternative to calling Ring method for each Participant individually. This also works with dialogs (with identities containing only one item).  * @param identities List of Participants to ring. Leaving the list empty will result in ringing all participants of at least speaker level.
    576             * @param videoCall If true, indicates that we want to do a video call (video still needs to be separately enabled)
    577             * @param origin When call is initiated from web link, this argument must contain the URI that was used
    578             */
    579            public void ringOthers(String[] identities, boolean videoCall, String origin) {
    580                    try {
    581                            sidDoRequest(ringOthers_req)
    582                            .addStringListParm(1, identities)                       .addBoolParm(2, videoCall)
    583                            .addStringParm(3, origin)
    584                            .endOneWay();
    585                    } catch(IOException e) {
    586                            mSidRoot.sidOnFatalError(e);
    587                    }
    588            }
    589            private final static byte[] muteMyMicrophone_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 11};
    590            /** Sets VOICE_STATUS to LISTENING in the Participant instance associated with us, causing any input from our microphone to be ignored. This is a Conversation class method, rather than Participant class, because this only applies to local participant.  */
    591            public void muteMyMicrophone() {
    592                    try {
    593                            sidDoRequest(muteMyMicrophone_req)
    594                            .endOneWay();
    595                    } catch(IOException e) {
    596                            mSidRoot.sidOnFatalError(e);
    597                    }
    598            }
    599            private final static byte[] unmuteMyMicrophone_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 12};
    600            /** Sets VOICE_STATUS to SPEAKING in the Participant instance associated with us, causing any input from our microphone to be sent to the call host. This is a Conversation class method, rather than Participant class, because this only applies to local participant.  */
    601            public void unmuteMyMicrophone() {
    602                    try {
    603                            sidDoRequest(unmuteMyMicrophone_req)
    604                            .endOneWay();
    605                    } catch(IOException e) {
    606                            mSidRoot.sidOnFatalError(e);
    607                    }
    608            }
    609            private final static byte[] holdMyLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 13};
    610            /** Puts the conversation on hold - Conversation LOCAL_LIVESTATUS changes to ON_HOLD_LOCALLY and to ON_HOLD_REMOTELY for remote participants.  */
    611            public void holdMyLiveSession() {
    612                    try {
    613                            sidDoRequest(holdMyLiveSession_req)
    614                            .endOneWay();
    615                    } catch(IOException e) {
    616                            mSidRoot.sidOnFatalError(e);
    617                    }
    618            }
    619            private final static byte[] resumeMyLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 14};
    620            /** Resumes call from local hold.  */
    621            public void resumeMyLiveSession() {
    622                    try {
    623                            sidDoRequest(resumeMyLiveSession_req)
    624                            .endOneWay();
    625                    } catch(IOException e) {
    626                            mSidRoot.sidOnFatalError(e);
    627                    }
    628            }
    629            private final static byte[] leaveLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 15};
    630            /** Hang up or refuse to answer an incoming call. Set postVoiceAutoresponse to true to enable a caller to leave a voicemail message.  * @param postVoiceAutoresponse
    631             */
    632            public void leaveLiveSession(boolean postVoiceAutoresponse) {
    633                    try {
    634                            sidDoRequest(leaveLiveSession_req)
    635                            .addBoolParm(1, postVoiceAutoresponse)
    636                            .endOneWay();
    637                    } catch(IOException e) {
    638                            mSidRoot.sidOnFatalError(e);
    639                    }
    640            }
    641            private final static byte[] startVoiceMessage_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 45};
    642            /** Begin recording a voice mail for this conversation's remote participant. Applies to conversations of type DIALOG only.  */
    643            public void startVoiceMessage() {
    644                    try {
    645                            sidDoRequest(startVoiceMessage_req)
    646                            .endOneWay();
    647                    } catch(IOException e) {
    648                            mSidRoot.sidOnFatalError(e);
    649                    }
    650            }
    651            private final static byte[] transferLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 40};
    652            /**
    653             * This method is for doing call transfers. NB! Call transfers only work in one-on-one conversations (dialogs). Before attempting call transfer, you should check availability of transfer recipients with Conversation class CanTransferLiveSession method. If the current conversation has a live session up, that session (call) will be transferred to targets specified in the identities list. Note that identities is a string list - all identities in that list will get incoming calls. The first one of them to pick up the call - wins, and rest of the transfer targets will stop ringing.
    654             *
    655             * Let's take a closer look how this works in practice. We have three call participants involved in the process, and two separate conversations. Let there be three callers: Caller A (call originator), Caller B (transferor) and Caller C (recipient of transfer).
    656             *
    657             *  - Caller A - calls Caller B; Caller B picks up the call - live conversation C1 is now up with A and B in it.
    658             *  - After awhile, Caller B initiates call transfers to Caller C (and optionally to Callers D, E, F.. ). LOCAL_LIVESTATUS of C1 will get set to TRANSFERRING for both A and B.
    659             *  - Caller C picks up the call. Conversation C1 will go off live status. For Caller B, conversation C1 LOCAL_LIVESTATUS will change to RECENTLY_LIVE. Another live conversation - C2 gets spawned, with Caller A and Caller C in it. For caller C, participant object representing caller A will have TRANSFERRED_BY property set to identity of caller A. For Caller B (in now no longer live conversation C1), participant object representing caller A gets its TRANSFERRED_TO property set to identity of caller C.
    660             * @param identities String list of transfer target identities. As soon as first one in this list picks up the call, others will stop ringing.
    661             * @param transferTopic Optional conversation topic. This value will get set as META_TOPIC property of the conversation at the transferee end. Note that this is the only case where META_TOPIC field is used in context of dialog conversations. Thus assumption that remote UI will display topic field in case of dialogs may not be 100% correct.
    662             */
    663            public void transferLiveSession(String[] identities, String transferTopic) {
    664                    try {
    665                            sidDoRequest(transferLiveSession_req)
    666                            .addStringListParm(1, identities)
    667                            .addStringParm(2, transferTopic)
    668                            .endOneWay();
    669                    } catch(IOException e) {
    670                            mSidRoot.sidOnFatalError(e);
    671                    }
    672            }
    673            private final static byte[] canTransferLiveSession_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 46};
    674            /** Checks if the identity is available for receiving a transferred live session. If you are going to attempt to go for multiple transfer targets, you should use this check for all the target identities.  * @param identity Target identity.
    675             * @return result Returns true if call transfer to given target is possible.
    676             */
    677            public boolean canTransferLiveSession(String identity) {
    678                    try {
    679                            return sidDoRequest(canTransferLiveSession_req)
    680                            .addStringParm(1, identity)
    681                            .endRequest().getBoolParm(1, true);
    682                    } catch(IOException e) {
    683                            mSidRoot.sidOnFatalError(e);
    684                            return false
    685                    ;}
    686            }
    687            private final static byte[] sendDtmf_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 16};
    688            /** Sends DTMF tone to a live conversation.  * @param dtmf Outgoing dtmf tone, possible values come from Participant.DTMF enumerator.
    689             * @param lengthInMs Duration in milliseconds. Defaults to 260 ms. Note that the DTMF tone can be also cancelled with Conversation.StopSendDTMF method.
    690             */
    691            public void sendDtmf(Participant.Dtmf dtmf, int lengthInMs) {
    692                    try {
    693                            sidDoRequest(sendDtmf_req)
    694                            .addEnumParm(1, dtmf)
    695                            .addUintParm(2, lengthInMs, 260)
    696                            .endOneWay();
    697                    } catch(IOException e) {
    698                            mSidRoot.sidOnFatalError(e);
    699                    }
    700            }
    701            private final static byte[] stopSendDtmf_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 48};
    702            /** Stops the current DTMF tone being played into conversation. For example, use this method to cancel DTMF signals started with Conversation.SendDTMF before the duration given in lengthInMS runs out.  */
    703            public void stopSendDtmf() {
    704                    try {
    705                            sidDoRequest(stopSendDtmf_req)
    706                            .endOneWay();
    707                    } catch(IOException e) {
    708                            mSidRoot.sidOnFatalError(e);
    709                    }
    710            }
    711            private final static byte[] setMyTextStatusTo_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 18};
    712            /** Sets local user typing indicator in the Conversation. Remote Participants can display these in their UI.  * @param status Typing indicator status value - Participant.TEXT_STATUS
    713             */
    714            public void setMyTextStatusTo(Participant.TextStatus status) {
    715                    try {
    716                            sidDoRequest(setMyTextStatusTo_req)
    717                            .addEnumParm(1, status)
    718                            .endOneWay();
    719                    } catch(IOException e) {
    720                            mSidRoot.sidOnFatalError(e);
    721                    }
    722            }
    723            private final static byte[] postText_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 19};
    724            /** Posts the specified text the conversation, and populates message with a reference to the corresponding Message object (if no error occurred during execution). The isXML argument can be used if the client UI has already taken care of converting message text to xml (for example, your UI might enable users to use bold tags in text messages.)  * @param text Text value of the outgoing message (gets set as BODY_XML property of the Message object).
    725             * @param isXml For cases where the text argument was already encoded as xml message.    * @return message Returns the Message object created as a result of this method (if successful).
    726             */
    727            public Message postText(String text, boolean isXml) {
    728                    try {
    729                            return (Message) sidDoRequest(postText_req)
    730                            .addStringParm(1, text)
    731                            .addBoolParm(2, isXml)
    732                            .endRequest().getObjectParm(1, 9, true);
    733                    } catch(IOException e) {
    734                            mSidRoot.sidOnFatalError(e);
    735                            return null
    736                    ;}
    737            }
    738            private final static byte[] postContacts_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 20};
    739            /**
    740             * Takes a list of Contacts as an argument and posts the list into the Conversation. The purpose of this feature is to enable sharing contacts between users, without resorting to contact search. Instead, if user A has contacts B and C, he can post contact C into chat with contact B. At this point, Contact B can add contact C to his contact list. From remote side, the posted contacts will appear as messages with type Message.POSTED_CONTACTS appearing in the conversation. The UI should allow adding these contacts from messages with this type into the contact list.
    741             *
    742             * The list of posted contacts can be retrieved with the Message.GetContacts method.
    743             *
    744             * Additionally, the UI then can parse the posted Contact data out of the Message.P_BODY_XML property. The list of contacts is wrapped between <contacts ..> </contacts> tags. Each contact item in the xml has following format:
    745             *  - t - contact type. "s" - skype contact; "p" - phone number;
    746             *  - s - skypename, present only in skypename contacts (t="s")
    747             *  - p - phone number, present only in phone number contacts (t="p")
    748             *  - f - contact's full name, if available
    749             *  - d - contact's display name, if available
    750             *
    751             * Note that only the type (t) field is mandatory. Depending on type, either skypename (s) or phone number (p) fields are always present. Full name and display name fields are optional.
    752             *
    753             * Example BODY_XML with skypname contact:
    754             * @code
    755             * <contacts alt="alt text"><c t="s" s="skypename" f="full name"/></contacts>
    756             * </CODE>
    757             *
    758             * Example BODY_XML with PSTN contact:
    759             * @code
    760             * <contacts alt="alt text"><c t="p" p="+37212345678" d="Some PSTN number"/></contacts>
    761             * </CODE>
    762             *
    763             * Example BODY_XML with multiple contacts:
    764             * @code
    765             * <contacts alt="alt text"><c t="p" p="+37212345678" d="Some PSTN number"/><c t="s" s="someskypename"/></contacts>
    766             * </CODE>
    767             * @param contacts List of Contact objects, to be posted in the conversation.
    768             */
    769            public void postContacts(Contact[] contacts) {
    770                    try {
    771                            sidDoRequest(postContacts_req)
    772                            .addObjectListParm(1, contacts)
    773                            .endOneWay();
    774                    } catch(IOException e) {
    775                            mSidRoot.sidOnFatalError(e);
    776                    }
    777            }
    778            private final static byte[] postFiles_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 21};
    779            public class PostFilesResponse {
    780                    public Skype.TransferSendfileError errorCode;
    781                    public String errorFile;
    782            };
    783
    784            /** Takes a list of fully-qualified filenames and initiates corresponding file transfers in the conversation. From the remote side, incoming file transfers will appear as a conversation message with type POSTED_FILES. Once such a message is detected, the list of file transfer objects can be retrieved with Message.GetTransfers. At that point, remote participants will need to accept or decline those transfers.  * @param paths list of fully-qualified filenames to be transferred
    785             * @param body Optional BODY_XML property for POSTED_FILES type messages that show up in remote UI.
    786             * @return PostFilesResponse
    787             * <br> - errorCode Error code, possible values come from the TRANSFER_SENDFILE_ERROR enumerator. This will be set for the first failed fail. The failed file is identified in the error_file return argument.
    788             * <br> - errorFile Filename of the file that triggered error.
    789             */
    790            public PostFilesResponse postFiles(String[] paths, String body) {
    791                    try {
    792                            Decoding decoder = sidDoRequest(postFiles_req)
    793                            .addFilenameListParm(1, paths)
    794                            .addStringParm(2, body)
    795                            .endRequest();
    796                            PostFilesResponse result = new PostFilesResponse();
    797                            result.errorCode = (Skype.TransferSendfileError) decoder.getEnumParm(1, Skype.TransferSendfileError.get(0), false);
    798                            result.errorFile = decoder.getFilenameParm(2, true);
    799                            return result;
    800                    } catch(IOException e) {
    801                            mSidRoot.sidOnFatalError(e);
    802                            return null
    803                    ;}
    804            }
    805            private final static byte[] postVoiceMessage_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 22};
    806            /** Stops the active voicemail recording and sends it (dialog only) * @param voicemail This argument is deprecated as of SDK version 3.2. Instead of manually constructing Voicemail object, you can call Conversation.StartVoiceMessage method to start recording a voicemail in context of a dialog. PostVoiceMessage will stop recording this voicemail and post it in the dialog. If instead of sending Voicemail, the user decides to cancel it, you should use Conversation.LeaveLiveSession method (Voicemail.Cancel is deprecated).
    807             * @param body Optional text message that remote UI can display in conversation, to notify the user of a new voicemail.
    808             */
    809            public void postVoiceMessage(Voicemail voicemail, String body) {
    810                    try {
    811                            sidDoRequest(postVoiceMessage_req)
    812                            .addObjectParm(1, voicemail)
    813                            .addStringParm(2, body)
    814                            .endOneWay();
    815                    } catch(IOException e) {
    816                            mSidRoot.sidOnFatalError(e);
    817                    }
    818            }
    819            private final static byte[] postSms_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 23};
    820            /** Takes an SMS instance created by Skype.CreateOutgoingSms and posts it in the conversation. Note that you will need to set both Sms body text (Sms.SetBody) and recipient list (Sms.SetTargets) before you can post the object.  * @param sms SMS object.
    821             * @param body This argument is currently ignored. The message text needs to be set with Sms.SetBody method, prior to passing the Sms object to this method
    822             */
    823            public void postSms(Sms sms, String body) {
    824                    try {
    825                            sidDoRequest(postSms_req)
    826                            .addObjectParm(1, sms)
    827                            .addStringParm(2, body)
    828                            .endOneWay();
    829                    } catch(IOException e) {
    830                            mSidRoot.sidOnFatalError(e);
    831                    }
    832            }
    833            private final static byte[] getJoinBlob_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 24};
    834            /**
    835             * Retrieves a binary join blob for joining public conversations, which are always of type CONFERENCE. If called for a dialog, the blob argument will contain the empty string. The best way to create a Public Chat is to first create a fresh conversation with Skype class CreateConference, then minimally apply the public chat options OPT_JOINING_ENABLED and OPT_ENTRY_LEVEL_RANK - options, like this (C++):
    836             * @code
    837             * C->SetOption(Conversation.OPT_JOINING_ENABLED, true);
    838             * </CODE>
    839             *
    840             * When that is done, you can call GetJoinBlob to retrieve the blob string. Use the blob string to generate and post an HTML link whose href attribute looks like this: href="skype:?chat&blob=_BLOB_GOES_HERE" A person running Skype desktop client can click this link to join the conversation and have that conversation opened in his UI. Note that the conversation host (creator) needs to be online for new joiners-via-link to start participating in the Public Chat.
    841             * @return blob Returns the public conversation join blob.
    842             */
    843            public String getJoinBlob() {
    844                    try {
    845                            return sidDoRequest(getJoinBlob_req)
    846                            .endRequest().getStringParm(1, true);
    847                    } catch(IOException e) {
    848                            mSidRoot.sidOnFatalError(e);
    849                            return ""
    850                    ;}
    851            }
    852            private final static byte[] join_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 25};
    853            /** Tries to join a public conversation (aka public chat). This method is only useful if you have used Skype.GetConversationByBlob method with alsoJoin argument set to false.  */
    854            public void join() {
    855                    try {
    856                            sidDoRequest(join_req)
    857                            .endOneWay();
    858                    } catch(IOException e) {
    859                            mSidRoot.sidOnFatalError(e);
    860                    }
    861            }
    862            private final static byte[] enterPassword_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 26};
    863            /** Submits password for joining password-protected conversation.  * @param password Password string.
    864             */
    865            public void enterPassword(String password) {
    866                    try {
    867                            sidDoRequest(enterPassword_req)
    868                            .addStringParm(1, password)
    869                            .endOneWay();
    870                    } catch(IOException e) {
    871                            mSidRoot.sidOnFatalError(e);
    872                    }
    873            }
    874            private final static byte[] setPassword_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 27};        /** Sets password protection/new password for the conversation.  * @param password New password.
    875             * @param hint Password hint.
    876             */
    877            public void setPassword(String password, String hint) {
    878                    try {
    879                            sidDoRequest(setPassword_req)
    880                            .addStringParm(1, password)
    881                            .addStringParm(2, hint)
    882                            .endOneWay();
    883                    } catch(IOException e) {
    884                            mSidRoot.sidOnFatalError(e);
    885                    }
    886            }
    887            private final static byte[] retireFrom_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 28};
    888            /** Leaves the conference. Not applicable to dialogs.  */
    889            public void retireFrom() {
    890                    try {
    891                            sidDoRequest(retireFrom_req)
    892                            .endOneWay();
    893                    } catch(IOException e) {
    894                            mSidRoot.sidOnFatalError(e);
    895                    }
    896            }
    897            private final static byte[] delete_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 47};
    898            /** Deletes this conversation, which must be of type CONFERENCE - dialogs between local user and any of his contacts are always persistant. Note that this also removes corresponding Message and Participant objects.  */
    899            public void delete() {
    900                    try {
    901                            sidDoRequest(delete_req)
    902                            .endOneWay();
    903                    } catch(IOException e) {
    904                            mSidRoot.sidOnFatalError(e);
    905                    }
    906            }
    907            private final static byte[] renameTo_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 29};
    908            /** Changes the META_NAME property of the conversation. Note that unlike topic and guidelines, this rename is just local - remote participants can have their own private names for conversations.  * @param name New name for the conversation. Passing an empty string in this argument causes the META_NAME to unset.
    909             */
    910            public void renameTo(String name) {
    911                    try {
    912                            sidDoRequest(renameTo_req)
    913                            .addStringParm(1, name)
    914                            .endOneWay();
    915                    } catch(IOException e) {
    916                            mSidRoot.sidOnFatalError(e);
    917                    }
    918            }
    919            private final static byte[] setBookmark_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 30};
    920            /** Setter for Conversation class IS_BOOKMARKED.  * @param bookmark Set true to set the bookmark, false to remove the bookmark.
    921             */
    922            public void setBookmark(boolean bookmark) {
    923                    try {
    924                            sidDoRequest(setBookmark_req)
    925                            .addBoolParm(1, bookmark)
    926                            .endOneWay();
    927                    } catch(IOException e) {
    928                            mSidRoot.sidOnFatalError(e);
    929                    }
    930            }
    931            private final static byte[] setAlertString_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 31};
    932            /** Setter for Conversation class ALERT_STRING property. The main use of this property is checking bodies of incoming messages in the conversation for the alert string and producing notifications in UI for the user, when appropriate.  * @param alertString Substring to check in BODY_XML property of incoming messages.
    933             */
    934            public void setAlertString(String alertString) {
    935                    try {
    936                            sidDoRequest(setAlertString_req)
    937                            .addStringParm(1, alertString)
    938                            .endOneWay();
    939                    } catch(IOException e) {
    940                            mSidRoot.sidOnFatalError(e);
    941                    }
    942            }
    943            private final static byte[] removeFromInbox_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 32};
    944            /** Removes conversation from Inbox.  */
    945            public void removeFromInbox() {
    946                    try {
    947                            sidDoRequest(removeFromInbox_req)
    948                            .endOneWay();
    949                    } catch(IOException e) {
    950                            mSidRoot.sidOnFatalError(e);
    951                    }
    952            }
    953            private final static byte[] addToInbox_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 33};
    954            /** Sets Conversation inbox_timestamp property. If the timestamp argument is left empty or is greater than conversation consumption horizon, then the conversation will be restored to the inbox.  * @param timestamp If left empty or set to 0, the inbox_timestamp property is set to current time.
    955             */
    956            public void addToInbox(int timestamp) {
    957                    try {
    958                            sidDoRequest(addToInbox_req)
    959                            .addUintParm(1, timestamp)
    960                            .endOneWay();
    961                    } catch(IOException e) {
    962                            mSidRoot.sidOnFatalError(e);
    963                    }
    964            }
    965            private final static byte[] setConsumedHorizon_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 34};
    966            /** This method can be used to set the consumption (read) status of messages in the conversation. It sets Message.CONSUMPTION_STATUS to Message.CONSUMED for all messages in the conversation, older than the given timestamp. If the second argument is set to true, it also modifies messages more recent than the timestamp, by marking them as unconsumed.  * @param timestamp Consumption cutoff timestamp. Setting this to current time will mark all messages in the conversation as consumed.
    967             * @param alsoUnconsume If set to true, this also marks messages newer than the cutoff timestamp as unconsumed. For example, setting timestamp to 0 and also_unconsumed to true, will unconsume all messages in the conversation.
    968             */
    969            public void setConsumedHorizon(int timestamp, boolean alsoUnconsume) {
    970                    try {
    971                            sidDoRequest(setConsumedHorizon_req)
    972                            .addUintParm(1, timestamp)
    973                            .addBoolParm(2, alsoUnconsume)
    974                            .endOneWay();
    975                    } catch(IOException e) {
    976                            mSidRoot.sidOnFatalError(e);
    977                    }
    978            }
    979            private final static byte[] markUnread_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 35};
    980            /** sets consumption horizon to last inbox message id timestamp */
    981            public void markUnread() {
    982                    try {
    983                            sidDoRequest(markUnread_req)
    984                            .endOneWay();
    985                    } catch(IOException e) {
    986                            mSidRoot.sidOnFatalError(e);
    987                    }
    988            }
    989            private final static byte[] isMemberOf_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 37};
    990            /** Checks if the conversation is a member of the given ContactGroup  * @param group ContactGroup
    991             * @return result True if this conversation is a member of the ContactGroup specified by the group argument contains the conversation
    992             */
    993            public boolean isMemberOf(ContactGroup group) {
    994                    try {
    995                            return sidDoRequest(isMemberOf_req)
    996                            .addObjectParm(1, group)
    997                            .endRequest().getBoolParm(1, true);
    998                    } catch(IOException e) {
    999                            mSidRoot.sidOnFatalError(e);
    1000                            return false
    1001                    ;}
    1002            }
    1003            private final static byte[] getParticipants_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 38};
    1004            /** Retrieves the list of this conversation's current participants, which you can optionally request to be filtered. If no Participants pass the filter, an empty list will be returned (the method itself still returns true).  * @param filter Conversation.PARTICIPANTFILTER - defaults to Conversation.ALL
    1005             * @return participants List of conversation Participant objects that passed the filter.
    1006             */
    1007            public Participant[] getParticipants(ParticipantFilter filter) {
    1008                    try {
    1009                            return (Participant[]) sidDoRequest(getParticipants_req)
    1010                            .addEnumParm(1, filter)
    1011                            .endRequest().getObjectListParm(1, 19, true);
    1012                    } catch(IOException e) {
    1013                            mSidRoot.sidOnFatalError(e);
    1014                            return null
    1015                    ;}
    1016            }
    1017            private final static byte[] getLastMessages_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 39};
    1018            public class GetLastMessagesResponse {
    1019                    public Message[] contextMessages;
    1020                    public Message[] unconsumedMessages;
    1021            };
    1022
    1023            /** Returns recent messages. The messages are returned in two lists - new messages (unconsumed) and recent message history (context messages). The context message list contains messages that are already above the consumption horizon but are fairly recent, making it likely that displaying them in UI would be good default behaviour.  * @param requireTimestamp If set to a non-zero value, includes messages no earlier than this timestamp, if not, includes messages from the last 24 hours only
    1024             * @return GetLastMessagesResponse
    1025             * <br> - contextMessages Already consumed messages, provided for context
    1026             * <br> - unconsumedMessages Unconsumed messages
    1027             */
    1028            public GetLastMessagesResponse getLastMessages(int requireTimestamp) {
    1029                    try {
    1030                            Decoding decoder = sidDoRequest(getLastMessages_req)
    1031                            .addUintParm(1, requireTimestamp)
    1032                            .endRequest();
    1033                            GetLastMessagesResponse result = new GetLastMessagesResponse();
    1034                            result.contextMessages = (Message[]) decoder.getObjectListParm(1, 9, false);
    1035                            result.unconsumedMessages = (Message[]) decoder.getObjectListParm(2, 9, true);
    1036                            return result;
    1037                    } catch(IOException e) {
    1038                            mSidRoot.sidOnFatalError(e);
    1039                            return null
    1040                    ;}
    1041            }
    1042            private final static byte[] findMessage_req = {(byte) 90,(byte) 82,(byte) 18,(byte) 41};
    1043            /** Finds the most recent Message object in the conversation that contains the substring specified by the text argument. If no matching messages are found, this method will return false. The search proceeds backwards in time, starting from the timestamp argument. To continue searching, you can start with timestamp=MAX_UINT, retrieve the TIMESTAMP property of the matching message, decrement it by one, and submit it as timestamp for the next FindMessage call.  * @param text Substring to search for.    * @param fromTimestampUp
    1044             * @return message Returns matching message or 0 if there was no match. As the likelihood of this object being invalid is quite high, you should always check for method return value before you start calling methods of this object.
    1045             */
    1046            public Message findMessage(String text, int fromTimestampUp) {
    1047                    try {
    1048                            return (Message) sidDoRequest(findMessage_req)
    1049                            .addStringParm(1, text)
    1050                            .addUintParm(2, fromTimestampUp, Integer.MIN_VALUE)
    1051                            .endRequest().getObjectParm(1, 9, true);
    1052                    } catch(IOException e) {
    1053                            mSidRoot.sidOnFatalError(e);
    1054                            return null
    1055                    ;}
    1056            }
    1057            /***
    1058             * generic multiget of a list of Property
    1059             * @param requested the list of requested properties of Conversation
    1060             * @return SidGetResponding
    1061             */
    1062            public SidGetResponding sidMultiGet(Property[] requested) {
    1063                    return super.sidMultiGet(requested);
    1064            }
    1065            /***
    1066             * generic multiget of list of Property for a list of Conversation
    1067             * @param requested the list of requested properties
    1068             * @return SidGetResponding[] can be casted to (Conversation[]) if all properties are cached
    1069             */
    1070            static public SidGetResponding[] sidMultiGet(Property[] requested, Conversation[] objects) {
    1071                    return SidObject.sidMultiGet(requested, objects);
    1072            }
    1073            /*** multiget the following properties
    1074             * - P_DISPLAY_NAME
    1075             * - P_UNCONSUMED_NORMAL_MESSAGES
    1076             * - P_INBOX_TIMESTAMP
    1077             */
    1078            public Conversation mgetInfo() {
    1079                    return (Conversation) super.sidMultiGet(Property.mget_info_mreq, this);
    1080            }
    1081            /*** multiget the following properties for a list of Conversation
    1082             * - P_DISPLAY_NAME
    1083             * - P_UNCONSUMED_NORMAL_MESSAGES
    1084             * - P_INBOX_TIMESTAMP
    1085             * @param objects targets of the request
    1086             * @return Conversation[] responses
    1087             */
    1088            static public Conversation[] mgetInfo(Conversation[] objects) {
    1089                    return (Conversation[]) SidObject.sidMultiGet(Property.mget_info_mreq, objects, objects);
    1090            }
    1091            /** contact identity in case of dialogs, chat name in case of conferences */
    1092            public String getIdentity() {
    1093                    synchronized(this) {
    1094                            if ((mSidCached & 0x1) != 0)
    1095                                    return mIdentity;
    1096                    }
    1097                    return sidRequestStringProperty(Property.P_IDENTITY);
    1098            }
    1099            /** type of the conversation */
    1100            public Type getType() {
    1101                    synchronized(this) {
    1102                            if ((mSidCached & 0x2) != 0)
    1103                                    return mType;
    1104                    }
    1105                    return (Type) sidRequestEnumProperty(Property.P_TYPE);
    1106            }
    1107            /** host of current live session. none => no session. myself in case of 1:1 calls */
    1108            public String getLiveHost() {
    1109                    synchronized(this) {
    1110                            if ((mSidCached & 0x4) != 0)
    1111                                    return mLiveHost;
    1112                    }
    1113                    return sidRequestStringProperty(Property.P_LIVE_HOST);
    1114            }
    1115            /** moment when first participant other than host joined the current or last live session */
    1116            public int getLiveStartTimestamp() {
    1117                    synchronized(this) {
    1118                            if ((mSidCached & 0x8) != 0)
    1119                                    return mLiveStartTimestamp;
    1120                    }
    1121                    return sidRequestUintProperty(Property.P_LIVE_START_TIMESTAMP);
    1122            }
    1123            /** if live session is muted */
    1124            public boolean getLiveIsMuted() {
    1125                    synchronized(this) {
    1126                            if ((mSidCached & 0x10) != 0)
    1127                                    return mLiveIsMuted;
    1128                    }
    1129                    return sidRequestBoolProperty(Property.P_LIVE_IS_MUTED);
    1130            }
    1131            /** '' everything matches, '=' nothing matches, '=string' string matches */
    1132            public String getAlertString() {
    1133                    synchronized(this) {
    1134                            if ((mSidCached & 0x20) != 0)
    1135                                    return mAlertString;
    1136                    }
    1137                    return sidRequestStringProperty(Property.P_ALERT_STRING);
    1138            }
    1139            /** if conversation is bookmarked/flagged */
    1140            public boolean getIsBookmarked() {
    1141                    synchronized(this) {
    1142                            if ((mSidCached & 0x40) != 0)
    1143                                    return mIsBookmarked;
    1144                    }
    1145                    return sidRequestBoolProperty(Property.P_IS_BOOKMARKED);
    1146            }
    1147            /** local name assigned via Rename */
    1148            public String getGivenDisplayName() {
    1149                    synchronized(this) {
    1150                            if ((mSidCached & 0x80) != 0)
    1151                                    return mGivenDisplayName;
    1152                    }
    1153                    return sidRequestStringProperty(Property.P_GIVEN_DISPLAY_NAME);
    1154            }
    1155            /** resulting display name of the conversation (based on given name, topic, participant list, etc) */
    1156            public String getDisplayName() {
    1157                    synchronized(this) {
    1158                            if ((mSidCached & 0x100) != 0)
    1159                                    return mDisplayName;
    1160                    }
    1161                    return sidRequestStringProperty(Property.P_DISPLAY_NAME);
    1162            }
    1163            /** if the conversation is live and in which status it is then */
    1164            public LocalLiveStatus getLocalLiveStatus() {
    1165                    synchronized(this) {
    1166                            if ((mSidCached & 0x200) != 0)
    1167                                    return mLocalLiveStatus;
    1168                    }
    1169                    return (LocalLiveStatus) sidRequestEnumProperty(Property.P_LOCAL_LIVE_STATUS);
    1170            }
    1171            /** timestamp to sort the conversations in inbox by. 0 means not in inbox */
    1172            public int getInboxTimestamp() {
    1173                    synchronized(this) {
    1174                            if ((mSidCached & 0x400) != 0)
    1175                                    return mInboxTimestamp;
    1176                    }
    1177                    return sidRequestUintProperty(Property.P_INBOX_TIMESTAMP);
    1178            }
    1179            /** ID of the message that caused INBOX_TIMESTAMP to be set */
    1180            public Message getInboxMessageId() {
    1181                    synchronized(this) {
    1182                            if ((mSidCached & 0x800) != 0)
    1183                                    return mInboxMessageId;
    1184                    }
    1185                    return (Message) sidRequestObjectProperty(Property.P_INBOX_MESSAGE_ID);
    1186            }
    1187            /** number of messages in UNCONSUMED_SUPPRESSED consumption status */
    1188            public int getUnconsumedSuppressedMessages() {
    1189                    synchronized(this) {
    1190                            if ((mSidCached & 0x1000) != 0)
    1191                                    return mUnconsumedSuppressedMessages;
    1192                    }
    1193                    return sidRequestUintProperty(Property.P_UNCONSUMED_SUPPRESSED_MESSAGES);
    1194            }
    1195            /** number of messages in UNCONSUMED_NORMAL consumption status */
    1196            public int getUnconsumedNormalMessages() {
    1197                    synchronized(this) {
    1198                            if ((mSidCached & 0x2000) != 0)
    1199                                    return mUnconsumedNormalMessages;
    1200                    }
    1201                    return sidRequestUintProperty(Property.P_UNCONSUMED_NORMAL_MESSAGES);
    1202            }
    1203            /** DEPRECATED, not set anymore */
    1204            public int getUnconsumedElevatedMessages() {
    1205                    synchronized(this) {
    1206                            if ((mSidCached & 0x4000) != 0)
    1207                                    return mUnconsumedElevatedMessages;
    1208                    }
    1209                    return sidRequestUintProperty(Property.P_UNCONSUMED_ELEVATED_MESSAGES);
    1210            }
    1211            /** if there are unconsumed voice or call messages in the conversation */
    1212            public boolean getUnconsumedMessagesVoice() {
    1213                    synchronized(this) {
    1214                            if ((mSidCached & 0x8000) != 0)
    1215                                    return mUnconsumedMessagesVoice;
    1216                    }
    1217                    return sidRequestBoolProperty(Property.P_UNCONSUMED_MESSAGES_VOICE);
    1218            }
    1219            /** ID of voice message that is being played or recorded in this conversation */
    1220            public Voicemail getActiveVoicemail() {
    1221                    synchronized(this) {
    1222                            if ((mSidCached & 0x10000) != 0)
    1223                                    return mActiveVoicemail;
    1224                    }
    1225                    return (Voicemail) sidRequestObjectProperty(Property.P_ACTIVE_VOICEMAIL);
    1226            }
    1227            /** consumption cutoff timestamp: messages after (but not including) this are considered unconsumed */
    1228            public int getConsumptionHorizon() {
    1229                    synchronized(this) {
    1230                            if ((mSidCached & 0x20000) != 0)
    1231                                    return mConsumptionHorizon;
    1232                    }
    1233                    return sidRequestUintProperty(Property.P_CONSUMPTION_HORIZON);
    1234            }
    1235            /** timestamp of last activity in conversation */
    1236            public int getLastActivityTimestamp() {
    1237                    synchronized(this) {
    1238                            if ((mSidCached & 0x40000) != 0)
    1239                                    return mLastActivityTimestamp;
    1240                    }
    1241                    return sidRequestUintProperty(Property.P_LAST_ACTIVITY_TIMESTAMP);
    1242            }
    1243            /** dialog this conference was spawned from */
    1244            public Conversation getSpawnedFromConvoId() {
    1245                    synchronized(this) {
    1246                            if ((mSidCached & 0x80000) != 0)
    1247                                    return mSpawnedFromConvoId;
    1248                    }
    1249                    return (Conversation) sidRequestObjectProperty(Property.P_SPAWNED_FROM_CONVO_ID);
    1250            }
    1251            /** identity of conversation creator (doesn't apply to dialogs) */
    1252            public String getCreator() {
    1253                    synchronized(this) {
    1254                            if ((mSidCached & 0x100000) != 0)
    1255                                    return mCreator;
    1256                    }
    1257                    return sidRequestStringProperty(Property.P_CREATOR);
    1258            }
    1259            /** timestamp of creation, tells you how far you can retrieve messages */
    1260            public int getCreationTimestamp() {
    1261                    synchronized(this) {
    1262                            if ((mSidCached & 0x200000) != 0)
    1263                                    return mCreationTimestamp;
    1264                    }
    1265                    return sidRequestUintProperty(Property.P_CREATION_TIMESTAMP);
    1266            }
    1267            /** my status in this conversation (connecting, participating, retired, etc) (doesn't apply to dialogs) */
    1268            public MyStatus getMyStatus() {
    1269                    synchronized(this) {
    1270                            if ((mSidCached & 0x400000) != 0)
    1271                                    return mMyStatus;
    1272                    }
    1273                    return (MyStatus) sidRequestEnumProperty(Property.P_MY_STATUS);
    1274            }
    1275            /** if it's a public conversation (doesn't apply to dialogs) */
    1276            public boolean getOptJoiningEnabled() {
    1277                    synchronized(this) {
    1278                            if ((mSidCached & 0x800000) != 0)
    1279                                    return mOptJoiningEnabled;
    1280                    }
    1281                    return sidRequestBoolProperty(Property.P_OPT_JOINING_ENABLED);  }
    1282            /** rank that is auto-assigned at join (doesn't apply to dialogs) */
    1283            public Participant.Rank getOptEntryLevelRank() {
    1284                    synchronized(this) {
    1285                            if ((mSidCached & 0x1000000) != 0)
    1286                                    return mOptEntryLevelRank;
    1287                    }
    1288                    return (Participant.Rank) sidRequestEnumProperty(Property.P_OPT_ENTRY_LEVEL_RANK);
    1289            }
    1290            /** if history visible to new consumers (doesn't apply to dialogs) */
    1291            public boolean getOptDiscloseHistory() {
    1292                    synchronized(this) {
    1293                            if ((mSidCached & 0x2000000) != 0)
    1294                                    return mOptDiscloseHistory;
    1295                    }
    1296                    return sidRequestBoolProperty(Property.P_OPT_DISCLOSE_HISTORY);
    1297            }
    1298            /** activities that only ADMIN can do. Bitmap of ALLOWED_ACTIVITY values (doesn't apply to dialogs) */
    1299            public int getOptAdminOnlyActivities() {
    1300                    synchronized(this) {
    1301                            if ((mSidCached & 0x4000000) != 0)
    1302                                    return mOptAdminOnlyActivities;
    1303                    }
    1304                    return sidRequestIntProperty(Property.P_OPT_ADMIN_ONLY_ACTIVITIES);
    1305            }
    1306            /** public conversation password hint, use SetPassword to set (doesn't apply to dialogs) */
    1307            public String getPasswordHint() {
    1308                    synchronized(this) {
    1309                            if ((mSidCached & 0x8000000) != 0)
    1310                                    return mPasswordHint;
    1311                    }
    1312                    return sidRequestStringProperty(Property.P_PASSWORD_HINT);
    1313            }
    1314            /** deprecated, not used */
    1315            public String getMetaName() {
    1316                    synchronized(this) {
    1317                            if ((mSidCached & 0x10000000) != 0)
    1318                                    return mMetaName;
    1319                    }
    1320                    return sidRequestStringProperty(Property.P_META_NAME);
    1321            }
    1322            /** conversation topic (doesn't apply to dialogs) */
    1323            public String getMetaTopic() {
    1324                    synchronized(this) {
    1325                            if ((mSidCached & 0x20000000) != 0)
    1326                                    return mMetaTopic;
    1327                    }
    1328                    return sidRequestXmlProperty(Property.P_META_TOPIC);
    1329            }
    1330            /** guidelines (doesn't apply to dialogs) */
    1331            public String getMetaGuidelines() {
    1332                    synchronized(this) {
    1333                            if ((mSidCached & 0x40000000) != 0)
    1334                                    return mMetaGuidelines;
    1335                    }
    1336                    return sidRequestXmlProperty(Property.P_META_GUIDELINES);
    1337            }
    1338            /** conversation picture, in jpeg format (doesn't apply to dialogs) */
    1339            public byte[] getMetaPicture() {
    1340                    synchronized(this) {
    1341                            if ((mSidCached & 0x80000000) != 0)
    1342                                    return mMetaPicture;
    1343                    }
    1344                    return sidRequestBinaryProperty(Property.P_META_PICTURE);
    1345            }
    1346            public String sidGetStringProperty(final PropertyEnumConverting prop) {
    1347                    switch(prop.getId()) {
    1348                    case 972:
    1349                            return mIdentity;
    1350                    case 918:
    1351                            return mLiveHost;
    1352                    case 920:
    1353                            return mAlertString;
    1354                    case 925:
    1355                            return mGivenDisplayName;
    1356                    case 924:
    1357                            return mDisplayName;
    1358                    case 903:
    1359                            return mCreator;
    1360                    case 980:
    1361                            return mPasswordHint;
    1362                    case 910:
    1363                            return mMetaName;
    1364                    case 911:
    1365                            return mMetaTopic;
    1366                    case 913:
    1367                            return mMetaGuidelines;
    1368                    }
    1369                    return "";
    1370            }
    1371            public SidObject sidGetObjectProperty(final PropertyEnumConverting prop) {
    1372                    switch(prop.getId()) {
    1373                    case 973:
    1374                            return mInboxMessageId;
    1375                    case 971:
    1376                            return mActiveVoicemail;
    1377                    case 915:
    1378                            return mSpawnedFromConvoId;
    1379                    }
    1380                    return null;
    1381            }
    1382            public boolean sidGetBoolProperty(final PropertyEnumConverting prop) {
    1383                    switch(prop.getId()) {
    1384                    case 996:
    1385                            return mLiveIsMuted;
    1386                    case 921:
    1387                            return mIsBookmarked;
    1388                    case 970:
    1389                            return mUnconsumedMessagesVoice;
    1390                    case 922:
    1391                            return mOptJoiningEnabled;
    1392                    case 907:
    1393                            return mOptDiscloseHistory;
    1394                    }
    1395                    return false;
    1396            }
    1397            public int sidGetIntProperty(final PropertyEnumConverting prop) {
    1398                    switch(prop.getId()) {
    1399                    case 974:
    1400                            return mLiveStartTimestamp;
    1401                    case 928:
    1402                            return mInboxTimestamp;
    1403                    case 975:
    1404                            return mUnconsumedSuppressedMessages;
    1405                    case 976:
    1406                            return mUnconsumedNormalMessages;
    1407                    case 977:
    1408                            return mUnconsumedElevatedMessages;
    1409                    case 979:
    1410                            return mConsumptionHorizon;
    1411                    case 981:
    1412                            return mLastActivityTimestamp;
    1413                    case 904:
    1414                            return mCreationTimestamp;
    1415                    case 909:
    1416                            return mOptAdminOnlyActivities;
    1417                    }
    1418                    return 0;
    1419            }
    1420            public EnumConverting sidGetEnumProperty(final PropertyEnumConverting prop) {
    1421                    switch(prop.getId()) {
    1422                    case 902:
    1423                            return mType;
    1424                    case 927:
    1425                            return mLocalLiveStatus;
    1426                    case 919:
    1427                            return mMyStatus;
    1428                    case 906:
    1429                            return mOptEntryLevelRank;
    1430                    }
    1431                    return null;
    1432            }
    1433            public byte[] sidGetBinaryProperty(final PropertyEnumConverting prop) {
    1434                    assert(prop.getId() == 914);
    1435                    return mMetaPicture;
    1436            }
    1437            public String getPropertyAsString(final int prop) {
    1438                    switch (prop) {
    1439                    case 972: return getIdentity();
    1440                    case 902: return getType().toString();
    1441                    case 918: return getLiveHost();
    1442                    case 974: return Integer.toString(getLiveStartTimestamp());
    1443                    case 996: return Boolean.toString(getLiveIsMuted());
    1444                    case 920: return getAlertString();
    1445                    case 921: return Boolean.toString(getIsBookmarked());
    1446                    case 925: return getGivenDisplayName();
    1447                    case 924: return getDisplayName();
    1448                    case 927: return getLocalLiveStatus().toString();
    1449                    case 928: return Integer.toString(getInboxTimestamp());
    1450                    case 973: return Integer.toString(getInboxMessageId().getOid());
    1451                    case 975: return Integer.toString(getUnconsumedSuppressedMessages());
    1452                    case 976: return Integer.toString(getUnconsumedNormalMessages());
    1453                    case 977: return Integer.toString(getUnconsumedElevatedMessages());
    1454                    case 970: return Boolean.toString(getUnconsumedMessagesVoice());
    1455                    case 971: return Integer.toString(getActiveVoicemail().getOid());
    1456                    case 979: return Integer.toString(getConsumptionHorizon());
    1457                    case 981: return Integer.toString(getLastActivityTimestamp());
    1458                    case 915: return Integer.toString(getSpawnedFromConvoId().getOid());
    1459                    case 903: return getCreator();
    1460                    case 904: return Integer.toString(getCreationTimestamp());
    1461                    case 919: return getMyStatus().toString();
    1462                    case 922: return Boolean.toString(getOptJoiningEnabled());
    1463                    case 906: return getOptEntryLevelRank().toString();
    1464                    case 907: return Boolean.toString(getOptDiscloseHistory());
    1465                    case 909: return Integer.toString(getOptAdminOnlyActivities());
    1466                    case 980: return getPasswordHint();
    1467                    case 910: return getMetaName();
    1468                    case 914: return "<binary>";
    1469                    }
    1470                    return "<unkown>";
    1471            }
    1472            public String getPropertyAsString(final Property prop) {
    1473                    return getPropertyAsString(prop.getId());
    1474            }
    1475            protected void sidOnChangedProperty(final int propertyId, final int value, final String svalue) {
    1476                    final Property property = Property.get(propertyId);
    1477                    if (property == Property.P_UNKNOWN) return;
    1478                    final int idx = property.getIdx();
    1479                    if (idx != 0) {
    1480                            int bit  = 1<<((idx-1)%32);
    1481                            synchronized (this) {
    1482                                    mSidCached|=bit;
    1483                                    switch (propertyId) {
    1484                                    case 972:
    1485                                            if (svalue != null) mIdentity = svalue;
    1486                                            else mSidCached &=~bit;
    1487                                            break;
    1488                                    case 902: mType = Type.get(value); break;
    1489                                    case 918:
    1490                                            if (svalue != null) mLiveHost = svalue;
    1491                                            else mSidCached &=~bit;
    1492                                            break;
    1493                                    case 974: mLiveStartTimestamp = value; break;
    1494                                    case 996: mLiveIsMuted = value != 0; break;
    1495                                    case 920:
    1496                                            if (svalue != null) mAlertString = svalue;
    1497                                            else mSidCached &=~bit;
    1498                                            break;
    1499                                    case 921: mIsBookmarked = value != 0; break;
    1500                                    case 925:
    1501                                            if (svalue != null) mGivenDisplayName = svalue;
    1502                                            else mSidCached &=~bit;
    1503                                            break;
    1504                                    case 924:
    1505                                            if (svalue != null) mDisplayName = svalue;
    1506                                            else mSidCached &=~bit;
    1507                                            break;
    1508                                    case 927: mLocalLiveStatus = LocalLiveStatus.get(value); break;
    1509                                    case 928: mInboxTimestamp = value; break;
    1510                                    case 975: mUnconsumedSuppressedMessages = value; break;
    1511                                    case 976: mUnconsumedNormalMessages = value; break;
    1512                                    case 977: mUnconsumedElevatedMessages = value; break;
    1513                                    case 970: mUnconsumedMessagesVoice = value != 0; break;
    1514                                    case 979: mConsumptionHorizon = value; break;
    1515                                    case 981: mLastActivityTimestamp = value; break;
    1516                                    case 903:
    1517                                            if (svalue != null) mCreator = svalue;
    1518                                            else mSidCached &=~bit;
    1519                                            break;
    1520                                    case 904: mCreationTimestamp = value; break;
    1521                                    case 919: mMyStatus = MyStatus.get(value); break;
    1522                                    case 922: mOptJoiningEnabled = value != 0; break;
    1523                                    case 906: mOptEntryLevelRank = Participant.Rank.get(value); break;
    1524                                    case 907: mOptDiscloseHistory = value != 0; break;
    1525                                    case 909: mOptAdminOnlyActivities = value; break;
    1526                                    case 980:
    1527                                            if (svalue != null) mPasswordHint = svalue;
    1528                                            else mSidCached &=~bit;
    1529                                            break;
    1530                                    case 910:
    1531                                            if (svalue != null) mMetaName = svalue;
    1532                                            else mSidCached &=~bit;
    1533                                            break;
    1534                                    default: mSidCached|=bit; break;
    1535                                    }
    1536                            }
    1537                    }
    1538                    ConversationListener listener = ((Skype) mSidRoot).getConversationListener();
    1539                    if (listener != null)                   listener.onPropertyChange(this, property, value, svalue);
    1540            }
    1541            public void sidSetProperty(final PropertyEnumConverting prop, final String newValue) {
    1542                    final int propId = prop.getId();
    1543                    switch(propId) {
    1544                    case 972:
    1545                            mSidCached |= 0x1;
    1546                            mIdentity=  newValue;
    1547                            break;
    1548                    case 918:
    1549                            mSidCached |= 0x4;
    1550                            mLiveHost=  newValue;
    1551                            break;
    1552                    case 920:
    1553                            mSidCached |= 0x20;
    1554                            mAlertString=  newValue;
    1555                            break;
    1556                    case 925:
    1557                            mSidCached |= 0x80;
    1558                            mGivenDisplayName=  newValue;
    1559                            break;
    1560                    case 924:
    1561                            mSidCached |= 0x100;
    1562                            mDisplayName=  newValue;
    1563                            break;
    1564                    case 903:
    1565                            mSidCached |= 0x100000;
    1566                            mCreator=  newValue;
    1567                            break;
    1568                    case 980:
    1569                            mSidCached |= 0x8000000;
    1570                            mPasswordHint=  newValue;
    1571                            break;
    1572                    case 910:
    1573                            mSidCached |= 0x10000000;
    1574                            mMetaName=  newValue;
    1575                            break;
    1576                    case 911:
    1577                            mSidCached |= 0x20000000;
    1578                            mMetaTopic=  newValue;
    1579                            break;
    1580                    case 913:
    1581                            mSidCached |= 0x40000000;
    1582                            mMetaGuidelines=  newValue;
    1583                            break;
    1584                    }
    1585            }
    1586            public void sidSetProperty(final PropertyEnumConverting prop, final SidObject newValue) {
    1587                    final int propId = prop.getId();
    1588                    switch(propId) {
    1589                    case 973:
    1590                            mSidCached |= 0x800;
    1591                            mInboxMessageId= (Message) newValue;
    1592                            break;
    1593                    case 971:
    1594                            mSidCached |= 0x10000;
    1595                            mActiveVoicemail= (Voicemail) newValue;
    1596                            break;
    1597                    case 915:
    1598                            mSidCached |= 0x80000;
    1599                            mSpawnedFromConvoId= (Conversation) newValue;
    1600                            break;
    1601                    }
    1602            }
    1603            public void sidSetProperty(final PropertyEnumConverting prop, final int newValue) {
    1604                    final int propId = prop.getId();
    1605                    switch(propId) {
    1606                    case 902:
    1607                            mSidCached |= 0x2;
    1608                            mType= Type.get(newValue);
    1609                            break;
    1610                    case 974:
    1611                            mSidCached |= 0x8;
    1612                            mLiveStartTimestamp=  newValue;
    1613                            break;
    1614                    case 996:
    1615                            mSidCached |= 0x10;
    1616                            mLiveIsMuted= newValue != 0;
    1617                            break;
    1618                    case 921:
    1619                            mSidCached |= 0x40;
    1620                            mIsBookmarked= newValue != 0;
    1621                            break;
    1622                    case 927:
    1623                            mSidCached |= 0x200;
    1624                            mLocalLiveStatus= LocalLiveStatus.get(newValue);
    1625                            break;
    1626                    case 928:
    1627                            mSidCached |= 0x400;
    1628                            mInboxTimestamp=  newValue;
    1629                            break;
    1630                    case 975:
    1631                            mSidCached |= 0x1000;
    1632                            mUnconsumedSuppressedMessages=  newValue;
    1633                            break;
    1634                    case 976:
    1635                            mSidCached |= 0x2000;
    1636                            mUnconsumedNormalMessages=  newValue;
    1637                            break;
    1638                    case 977:
    1639                            mSidCached |= 0x4000;
    1640                            mUnconsumedElevatedMessages=  newValue;
    1641                            break;
    1642                    case 970:
    1643                            mSidCached |= 0x8000;
    1644                            mUnconsumedMessagesVoice= newValue != 0;
    1645                            break;
    1646                    case 979:
    1647                            mSidCached |= 0x20000;
    1648                            mConsumptionHorizon=  newValue;
    1649                            break;
    1650                    case 981:
    1651                            mSidCached |= 0x40000;
    1652                            mLastActivityTimestamp=  newValue;
    1653                            break;
    1654                    case 904:
    1655                            mSidCached |= 0x200000;
    1656                            mCreationTimestamp=  newValue;
    1657                            break;
    1658                    case 919:
    1659                            mSidCached |= 0x400000;
    1660                            mMyStatus= MyStatus.get(newValue);
    1661                            break;
    1662                    case 922:
    1663                            mSidCached |= 0x800000;
    1664                            mOptJoiningEnabled= newValue != 0;
    1665                            break;
    1666                    case 906:
    1667                            mSidCached |= 0x1000000;
    1668                            mOptEntryLevelRank= Participant.Rank.get(newValue);
    1669                            break;
    1670                    case 907:
    1671                            mSidCached |= 0x2000000;
    1672                            mOptDiscloseHistory= newValue != 0;
    1673                            break;
    1674                    case 909:
    1675                            mSidCached |= 0x4000000;
    1676                            mOptAdminOnlyActivities=  newValue;
    1677                            break;
    1678                    }
    1679            }
    1680            public void sidSetProperty(final PropertyEnumConverting prop, final byte[] newValue) {
    1681                    final int propId = prop.getId();
    1682                    assert(propId == 914);
    1683                    mSidCached |= 0x80000000;
    1684                    mMetaPicture=  newValue;
    1685            }
    1686            public String           mIdentity;
    1687            public Type             mType;
    1688            public String           mLiveHost;
    1689            public int              mLiveStartTimestamp;
    1690            public boolean          mLiveIsMuted;
    1691            public String           mAlertString;
    1692            public boolean          mIsBookmarked;
    1693            public String           mGivenDisplayName;
    1694            public String           mDisplayName;
    1695            public LocalLiveStatus  mLocalLiveStatus;
    1696            public int              mInboxTimestamp;
    1697            public Message          mInboxMessageId;
    1698            public int              mUnconsumedSuppressedMessages;
    1699            public int              mUnconsumedNormalMessages;
    1700            public int              mUnconsumedElevatedMessages;
    1701            public boolean          mUnconsumedMessagesVoice;
    1702            public Voicemail        mActiveVoicemail;
    1703            public int              mConsumptionHorizon;
    1704            public int              mLastActivityTimestamp;
    1705            public Conversation     mSpawnedFromConvoId;
    1706            public String           mCreator;
    1707            public int              mCreationTimestamp;
    1708            public MyStatus         mMyStatus;
    1709            public boolean          mOptJoiningEnabled;
    1710            public Participant.Rank mOptEntryLevelRank;
    1711            public boolean          mOptDiscloseHistory;
    1712            public int              mOptAdminOnlyActivities;
    1713            public String           mPasswordHint;
    1714            public String           mMetaName;
    1715            public String           mMetaTopic;
    1716            public String           mMetaGuidelines;
    1717            public byte[]           mMetaPicture;
    1718            public int moduleId() {
    1719                    return 18;
    1720            }
    1721
    1722            public Conversation(final int oid, final SidRoot root) {
    1723                    super(oid, root, 32);
    1724            }
    1725    }