// Path: src/main/java/org/kontalk/misc/JID.java
// public final class JID {
//     private static final Logger LOGGER = Logger.getLogger(JID.class.getName());
// 
//     static {
//         // good to know. For working JID validation
//         SimpleXmppStringprep.setup();
//     }
// 
//     private final String mLocal; // escaped!
//     private final String mDomain;
//     private final String mResource;
//     private final boolean mValid;
// 
//     private JID(String local, String domain, String resource) {
//         mLocal = local;
//         mDomain = domain;
//         mResource = resource;
// 
//         mValid = !mLocal.isEmpty() && !mDomain.isEmpty()
//                 // NOTE: domain check could be stronger - compliant with RFC 6122, but
//                 // server does not accept most special characters
//                 // NOTE: resource not checked
//                 && JidUtil.isTypicalValidEntityBareJid(
//                         XmppStringUtils.completeJidFrom(mLocal, mDomain));
//     }
// 
//     /** Return unescaped local part. */
//     public String local() {
//         return XmppStringUtils.unescapeLocalpart(mLocal);
//     }
// 
//     public String domain() {
//         return mDomain;
//     }
// 
//     /** Return JID as escaped string. */
//     public String string() {
//         return XmppStringUtils.completeJidFrom(mLocal, mDomain, mResource);
//     }
// 
//     public String asUnescapedString() {
//         return XmppStringUtils.completeJidFrom(this.local(), mDomain, mResource);
//     }
// 
//     public boolean isValid() {
//         return mValid;
//     }
// 
//     public boolean isHash() {
//         return mLocal.matches("[0-9a-f]{40}");
//     }
// 
//     public boolean isFull() {
//         return !mResource.isEmpty();
//     }
// 
//     public JID toBare() {
//         return new JID(mLocal, mDomain, "");
//     }
// 
//     /** To invalid(!) domain JID. */
//     public JID toDomain() {
//         return new JID("", mDomain, "");
//     }
// 
//     public BareJid toBareSmack() {
//         try {
//             return JidCreate.bareFrom(this.string());
//         } catch (XmppStringprepException ex) {
//             LOGGER.log(Level.WARNING, "could not convert to smack", ex);
//             throw new RuntimeException("You didn't check isValid(), idiot!");
//         }
//     }
// 
//     public Jid toSmack() {
//         try {
//             return JidCreate.from(this.string());
//         } catch (XmppStringprepException ex) {
//             LOGGER.log(Level.WARNING, "could not convert to smack", ex);
//             throw new RuntimeException("Not even a simple Jid?");
//         }
//     }
// 
//     /**
//      * Comparing only bare JIDs.
//      * Case-insensitive.
//      */
//     @Override
//     public final boolean equals(Object o) {
//         if (o == this)
//             return true;
// 
//        if (!(o instanceof JID))
//            return false;
// 
//        JID oJID = (JID) o;
//        return mLocal.equalsIgnoreCase(oJID.mLocal) &&
//                mDomain.equalsIgnoreCase(oJID.mDomain);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(mLocal, mDomain);
//     }
// 
//     /** Use this only for debugging and otherwise string() instead! */
//     @Override
//     public String toString() {
//         return "'"+this.string()+"'";
//     }
// 
//     public static JID full(String jid) {
//         jid = StringUtils.defaultString(jid);
//         return escape(XmppStringUtils.parseLocalpart(jid),
//                 XmppStringUtils.parseDomain(jid),
//                 XmppStringUtils.parseResource(jid));
//     }
// 
//     public static JID bare(String jid) {
//         jid = StringUtils.defaultString(jid);
//         return escape(XmppStringUtils.parseLocalpart(jid), XmppStringUtils.parseDomain(jid), "");
//     }
// 
//     public static JID fromSmack(Jid jid) {
//         Localpart localpart = jid.getLocalpartOrNull();
//         return new JID(localpart != null ? localpart.toString() : "",
//                 jid.getDomain().toString(),
//                 jid.getResourceOrEmpty().toString());
//     }
// 
//     public static JID bare(String local, String domain) {
//         return escape(local, domain, "");
//     }
// 
//     private static JID escape(String local, String domain, String resource) {
//         return new JID(XmppStringUtils.escapeLocalpart(local), domain, resource);
//     }
// 
//     public static JID deleted(int id) {
//         return new JID("", Integer.toString(id), "");
//     }
// }


import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.kontalk.misc.JID;
/*
 *  Kontalk Java client
 *  Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.kontalk.model.chat;


/**
 * Immutable meta data fields for a specific group chat protocol implementation.
 *
 * @author Alexander Bikadorov {@literal <bikaejkb@mail.tu-berlin.de>}
 */
public abstract class GroupMetaData {
    private static final Logger LOGGER = Logger.getLogger(GroupMetaData.class.getName());

    abstract String toJSON();

    /** Data fields specific to a Kontalk group chat (custom protocol). */
    public static class KonGroupData extends GroupMetaData {
        private static final String JSON_OWNER_JID = "jid";
        private static final String JSON_ID = "id";

// Path: src/main/java/org/kontalk/misc/JID.java
// public final class JID {
//     private static final Logger LOGGER = Logger.getLogger(JID.class.getName());
// 
//     static {
//         // good to know. For working JID validation
//         SimpleXmppStringprep.setup();
//     }
// 
//     private final String mLocal; // escaped!
//     private final String mDomain;
//     private final String mResource;
//     private final boolean mValid;
// 
//     private JID(String local, String domain, String resource) {
//         mLocal = local;
//         mDomain = domain;
//         mResource = resource;
// 
//         mValid = !mLocal.isEmpty() && !mDomain.isEmpty()
//                 // NOTE: domain check could be stronger - compliant with RFC 6122, but
//                 // server does not accept most special characters
//                 // NOTE: resource not checked
//                 && JidUtil.isTypicalValidEntityBareJid(
//                         XmppStringUtils.completeJidFrom(mLocal, mDomain));
//     }
// 
//     /** Return unescaped local part. */
//     public String local() {
//         return XmppStringUtils.unescapeLocalpart(mLocal);
//     }
// 
//     public String domain() {
//         return mDomain;
//     }
// 
//     /** Return JID as escaped string. */
//     public String string() {
//         return XmppStringUtils.completeJidFrom(mLocal, mDomain, mResource);
//     }
// 
//     public String asUnescapedString() {
//         return XmppStringUtils.completeJidFrom(this.local(), mDomain, mResource);
//     }
// 
//     public boolean isValid() {
//         return mValid;
//     }
// 
//     public boolean isHash() {
//         return mLocal.matches("[0-9a-f]{40}");
//     }
// 
//     public boolean isFull() {
//         return !mResource.isEmpty();
//     }
// 
//     public JID toBare() {
//         return new JID(mLocal, mDomain, "");
//     }
// 
//     /** To invalid(!) domain JID. */
//     public JID toDomain() {
//         return new JID("", mDomain, "");
//     }
// 
//     public BareJid toBareSmack() {
//         try {
//             return JidCreate.bareFrom(this.string());
//         } catch (XmppStringprepException ex) {
//             LOGGER.log(Level.WARNING, "could not convert to smack", ex);
//             throw new RuntimeException("You didn't check isValid(), idiot!");
//         }
//     }
// 
//     public Jid toSmack() {
//         try {
//             return JidCreate.from(this.string());
//         } catch (XmppStringprepException ex) {
//             LOGGER.log(Level.WARNING, "could not convert to smack", ex);
//             throw new RuntimeException("Not even a simple Jid?");
//         }
//     }
// 
//     /**
//      * Comparing only bare JIDs.
//      * Case-insensitive.
//      */
//     @Override
//     public final boolean equals(Object o) {
//         if (o == this)
//             return true;
// 
//        if (!(o instanceof JID))
//            return false;
// 
//        JID oJID = (JID) o;
//        return mLocal.equalsIgnoreCase(oJID.mLocal) &&
//                mDomain.equalsIgnoreCase(oJID.mDomain);
//     }
// 
//     @Override
//     public int hashCode() {
//         return Objects.hash(mLocal, mDomain);
//     }
// 
//     /** Use this only for debugging and otherwise string() instead! */
//     @Override
//     public String toString() {
//         return "'"+this.string()+"'";
//     }
// 
//     public static JID full(String jid) {
//         jid = StringUtils.defaultString(jid);
//         return escape(XmppStringUtils.parseLocalpart(jid),
//                 XmppStringUtils.parseDomain(jid),
//                 XmppStringUtils.parseResource(jid));
//     }
// 
//     public static JID bare(String jid) {
//         jid = StringUtils.defaultString(jid);
//         return escape(XmppStringUtils.parseLocalpart(jid), XmppStringUtils.parseDomain(jid), "");
//     }
// 
//     public static JID fromSmack(Jid jid) {
//         Localpart localpart = jid.getLocalpartOrNull();
//         return new JID(localpart != null ? localpart.toString() : "",
//                 jid.getDomain().toString(),
//                 jid.getResourceOrEmpty().toString());
//     }
// 
//     public static JID bare(String local, String domain) {
//         return escape(local, domain, "");
//     }
// 
//     private static JID escape(String local, String domain, String resource) {
//         return new JID(XmppStringUtils.escapeLocalpart(local), domain, resource);
//     }
// 
//     public static JID deleted(int id) {
//         return new JID("", Integer.toString(id), "");
//     }
// }


// Path: src/main/java/org/kontalk/model/chat/GroupMetaData.java
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.kontalk.misc.JID;

/*
 *  Kontalk Java client
 *  Copyright (C) 2016 Kontalk Devteam <devteam@kontalk.org>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.kontalk.model.chat;


/**
 * Immutable meta data fields for a specific group chat protocol implementation.
 *
 * @author Alexander Bikadorov {@literal <bikaejkb@mail.tu-berlin.de>}
 */
public abstract class GroupMetaData {
    private static final Logger LOGGER = Logger.getLogger(GroupMetaData.class.getName());

    abstract String toJSON();

    /** Data fields specific to a Kontalk group chat (custom protocol). */
    public static class KonGroupData extends GroupMetaData {
        private static final String JSON_OWNER_JID = "jid";
        private static final String JSON_ID = "id";

        public final JID owner;