public static Optional<Boolean> isTarget(EventModel eventModel, Identifiable identifiable) {
        if (eventModel.getListResourceContainer()
                .providesResource(Collections.singletonList(SelectorResource.RESOURCE_ID))) {
               return Optional.of(eventModel.getListResourceContainer()
                       .provideResource(SelectorResource.RESOURCE_ID)
                       .stream()
                       .map(ResourceModel::getResource)
                       .filter(resource -> resource instanceof Identification)
                       .map(object -> (Identification) object)
                       .anyMatch(identifiable::isOwner));
        } else {
            return Optional.empty();
        }
    }

public static Optional < Boolean > isTarget ( EventModel eventModel , Identifiable identifiable ) { if ( eventModel . getListResourceContainer ( ) . providesResource ( Collections . singletonList ( SelectorResource . RESOURCE_ID ) ) ) { return Optional . of ( eventModel . getListResourceContainer ( ) . provideResource ( SelectorResource . RESOURCE_ID ) . stream ( ) . map ( ResourceModel :: getResource ) . filter ( resource -> resource instanceof Identification ) . map ( object -> ( Identification ) object ) . anyMatch ( identifiable :: isOwner ) ) ; } else { return Optional . empty ( ) ; } }

returns true if the identifiable is the target of the EventModel
@param eventModel the EventModel to check
@param identifiable the identifiable to check against
@return maybe true if found


public void setLoginEnabled(long from, long to, boolean day, TimeZone timeZone) {
        String enabledSetting = EnabledPeriod.getEnableValue(from, to, day, timeZone);
        if (enabledSetting == null) {
            removeProperty(LOGIN_ENABLED_PERIOD_FIELD);
        } else {
            setProperty(LOGIN_ENABLED_PERIOD_FIELD, enabledSetting);
        }
    }

public void setLoginEnabled ( long from , long to , boolean day , TimeZone timeZone ) { String enabledSetting = EnabledPeriod . getEnableValue ( from , to , day , timeZone ) ; if ( enabledSetting == null ) { removeProperty ( LOGIN_ENABLED_PERIOD_FIELD ) ; } else { setProperty ( LOGIN_ENABLED_PERIOD_FIELD , enabledSetting ) ; } }

Sets the login enabled time

@param from
UTC ms time after which user login is enabled. < 0 means no
start time.
@param to
UTC ms time before which the user login is enabled, < 0 means
no end time.
@param day
true if the time represents a day rather than a time
@param timeZone
the timezone which both these times should be interpreted in
(relevant for a day setting).
@since 1.4


public static <E> Set<E> decorate(Set<E> set) {
        return new SynchronizedSet<E>(set);
    }

public static < E > Set < E > decorate ( Set < E > set ) { return new SynchronizedSet < E > ( set ) ; }

Factory method to create a synchronized set.

@param set  the set to decorate, must not be null
@throws IllegalArgumentException if set is null

Factory method to create a synchronized set .


public void setName(String name) {
        // Do nothing if the name hasn't changed.
        if (name != null && name.equals(this.name)) {
            return;
        }
        this.name = name;
        Roster packet = new Roster();
        packet.setType(IQ.Type.set);
        packet.addItem(new JID(user), name, ask, subscription, getGroupNames());
        connection.sendPacket(packet);
    }

Sets the name associated with this entry.

@param name
the name.

Sets the name associated with this entry .


void updateState(String name, Subscription type, Ask status) {
        this.name = name;
        this.subscription = type;
        this.ask = status;
    }

void updateState ( String name , Subscription type , Ask status ) { this . name = name ; this . subscription = type ; this . ask = status ; }

Updates the state of the entry with the new values.

@param name
the nickname for the entry.
@param type
the subscription type.
@param status
the subscription status (related to subscriptions pending to
be approbed).

Updates the state of the entry with the new values .


public Collection<RosterGroup> getGroups() {
        List<RosterGroup> results = new ArrayList<RosterGroup>();
        // Loop through all roster groups and find the ones that contain this
        // entry. This algorithm should be fine
        for (RosterGroup group : roster.getGroups()) {
            if (group.contains(this)) {
                results.add(group);
            }
        }
        return Collections.unmodifiableCollection(results);
    }

Returns an unmodifiable collection of the roster groups that this entry
belongs to.

@return an iterator for the groups this entry belongs to.

Returns an unmodifiable collection of the roster groups that this entry belongs to .


public static void appendRSMElement(Element queryElement, RSM rsm) {
        Element setElement = queryElement.addElement("set", RSM.NAMESPACE);

        if (rsm.getFirst() != null) {
            Element firstElement = setElement.addElement("first");
            firstElement.addAttribute("index", rsm.getIndex().toString());
            firstElement.setText(rsm.getFirst());
        }

        if (rsm.getLast() != null) {
            Element lastElement = setElement.addElement("last");
            lastElement.setText(rsm.getLast());
        }

        setElement.addElement("count").setText(String.valueOf(rsm.getCount()));
    }

public static void appendRSMElement ( Element queryElement , RSM rsm ) { Element setElement = queryElement . addElement ( "set" , RSM . NAMESPACE ) ; if ( rsm . getFirst ( ) != null ) { Element firstElement = setElement . addElement ( "first" ) ; firstElement . addAttribute ( "index" , rsm . getIndex ( ) . toString ( ) ) ; firstElement . setText ( rsm . getFirst ( ) ) ; } if ( rsm . getLast ( ) != null ) { Element lastElement = setElement . addElement ( "last" ) ; lastElement . setText ( rsm . getLast ( ) ) ; } setElement . addElement ( "count" ) . setText ( String . valueOf ( rsm . getCount ( ) ) ) ; }

Appends RSM info to query response.

@param queryElement
@param rsm


public static RSM parseRSM(Element queryElement) {
        RSM rsm = new RSM();

        Element setElement = queryElement.element("set");
        if (setElement == null) {
            return rsm;
        }

        Element after = setElement.element("after");
        if (after != null) {
            rsm.setAfter(after.getText());
        }

        Element before = setElement.element("before");
        if (before != null) {
            String beforeText = before.getText();
            rsm.setBefore(beforeText == null ? "" : beforeText);
        }

        Element index = setElement.element("index");
        if (index != null) {
            rsm.setIndex(Integer.parseInt(index.getText()));
        }

        Element max = setElement.element("max");
        if (max != null) {
            rsm.setMax(Integer.parseInt(max.getText()));
        }

        return rsm;
    }

public static RSM parseRSM ( Element queryElement ) { RSM rsm = new RSM ( ) ; Element setElement = queryElement . element ( "set" ) ; if ( setElement == null ) { return rsm ; } Element after = setElement . element ( "after" ) ; if ( after != null ) { rsm . setAfter ( after . getText ( ) ) ; } Element before = setElement . element ( "before" ) ; if ( before != null ) { String beforeText = before . getText ( ) ; rsm . setBefore ( beforeText == null ? "" : beforeText ) ; } Element index = setElement . element ( "index" ) ; if ( index != null ) { rsm . setIndex ( Integer . parseInt ( index . getText ( ) ) ) ; } Element max = setElement . element ( "max" ) ; if ( max != null ) { rsm . setMax ( Integer . parseInt ( max . getText ( ) ) ) ; } return rsm ; }

Parses an RSM from a query XML element

@param queryElement
@return The parsed RSM object


public static List<Identifiable> filterRSMResponse(
            List<Identifiable> objects, RSM rsm)
            throws IllegalArgumentException {

        String after = rsm.getAfter();
        String before = rsm.getBefore();

        int initialIndex = rsm.getIndex();
        int lastIndex = objects.size();

        if (after != null || (before != null && !before.isEmpty())) {

            boolean afterItemFound = false;
            boolean beforeItemFound = false;

            int i = 0;
            for (Identifiable object : objects) {
                if (after != null && after.equals(object.getId())) {
                    initialIndex = i + 1;
                    afterItemFound = true;
                }
                if (before != null && before.equals(object.getId())) {
                    lastIndex = i;
                    beforeItemFound = true;
                }
                i++;
            }

            if (after != null && !afterItemFound) {
                throw new IllegalArgumentException();
            }

            if (before != null && !before.isEmpty() && !beforeItemFound) {
                throw new IllegalArgumentException();
            }
        }

        if (rsm.getMax() != null) {
            if (before != null) {
                initialIndex = lastIndex - rsm.getMax();
            } else {
                lastIndex = initialIndex + rsm.getMax();
            }
        }

        boolean outOfRange = initialIndex > lastIndex || initialIndex < 0
                || lastIndex > objects.size();

        List<Identifiable> filteredList = outOfRange ? new LinkedList<Identifiable>()
                : objects.subList(initialIndex, lastIndex);

        rsm.setCount(objects.size());
        rsm.setIndex(initialIndex);

        if (!filteredList.isEmpty()) {
            rsm.setFirst(filteredList.get(0).getId());
            rsm.setLast(filteredList.get(filteredList.size() - 1).getId());
        }

        return filteredList;
    }

public static List < Identifiable > filterRSMResponse ( List < Identifiable > objects , RSM rsm ) throws IllegalArgumentException { String after = rsm . getAfter ( ) ; String before = rsm . getBefore ( ) ; int initialIndex = rsm . getIndex ( ) ; int lastIndex = objects . size ( ) ; if ( after != null || ( before != null && ! before . isEmpty ( ) ) ) { boolean afterItemFound = false ; boolean beforeItemFound = false ; int i = 0 ; for ( Identifiable object : objects ) { if ( after != null && after . equals ( object . getId ( ) ) ) { initialIndex = i + 1 ; afterItemFound = true ; } if ( before != null && before . equals ( object . getId ( ) ) ) { lastIndex = i ; beforeItemFound = true ; } i ++ ; } if ( after != null && ! afterItemFound ) { throw new IllegalArgumentException ( ) ; } if ( before != null && ! before . isEmpty ( ) && ! beforeItemFound ) { throw new IllegalArgumentException ( ) ; } } if ( rsm . getMax ( ) != null ) { if ( before != null ) { initialIndex = lastIndex - rsm . getMax ( ) ; } else { lastIndex = initialIndex + rsm . getMax ( ) ; } } boolean outOfRange = initialIndex > lastIndex || initialIndex < 0 || lastIndex > objects . size ( ) ; List < Identifiable > filteredList = outOfRange ? new LinkedList < Identifiable > ( ) : objects . subList ( initialIndex , lastIndex ) ; rsm . setCount ( objects . size ( ) ) ; rsm . setIndex ( initialIndex ) ; if ( ! filteredList . isEmpty ( ) ) { rsm . setFirst ( filteredList . get ( 0 ) . getId ( ) ) ; rsm . setLast ( filteredList . get ( filteredList . size ( ) - 1 ) . getId ( ) ) ; } return filteredList ; }

Filters response objects based on the RSM parameters. Updates the RSM
object with item count, first and last jid

@param objects
@param rsm
@return
@throws IllegalArgumentException
If the item specified by the requesting entity via the UID in
the <after/> or <before/> element does not exist

Filters response objects based on the RSM parameters . Updates the RSM object with item count first and last jid


public static Optional<LeavingEvent> createLeavingEvent(Identification source, boolean strict, List<String> descriptors) {
        try {
            if (strict) {
                descriptors.add(STRICT_DESCRIPTOR);
            } else {
                descriptors.add(GENERAL_DESCRIPTOR);
            }
            descriptors.add(ID);
            descriptors.add(CommonEvents.Descriptors.NOT_INTERRUPT);
            LeavingEvent stopRequest = new LeavingEvent(source, descriptors);
            return Optional.of(stopRequest);
        } catch (IllegalArgumentException e) {
            return Optional.empty();
        }
    }

public static Optional < LeavingEvent > createLeavingEvent ( Identification source , boolean strict , List < String > descriptors ) { try { if ( strict ) { descriptors . add ( STRICT_DESCRIPTOR ) ; } else { descriptors . add ( GENERAL_DESCRIPTOR ) ; } descriptors . add ( ID ) ; descriptors . add ( CommonEvents . Descriptors . NOT_INTERRUPT ) ; LeavingEvent stopRequest = new LeavingEvent ( source , descriptors ) ; return Optional . of ( stopRequest ) ; } catch ( IllegalArgumentException e ) { return Optional . empty ( ) ; } }

creates a new LeavingEvent
@param source the caller
@param strict whether the addon can guarantee that the user is around
@param descriptors the descriptors
@return the optional PresenceEvent


public void reload() {
        if (!connection.isAuthenticated()) {
            throw new IllegalStateException("Not logged in to server.");
        }
        if (connection.isAnonymous()) {
            throw new IllegalStateException(
                    "Anonymous users can't have a roster.");
        }

        Roster packet = new Roster();
        if (rosterStore != null && connection.isRosterVersioningSupported()) {
            packet.getElement().element("query")
                    .addAttribute("ver", rosterStore.getRosterVersion());
            PacketFilter filter = new PacketIDFilter(packet.getID());
            connection.addPacketListener(new RosterResultListener(), filter);
        }
        connection.sendPacket(packet);
    }

public
void
reload
(
)
{
if
(
!
connection
.
isAuthenticated
(
)
)
{
throw
new
IllegalStateException
(
"Not logged in to server."
)
;
}
if
(
connection
.
isAnonymous
(
)
)
{
throw
new
IllegalStateException
(
"Anonymous users can't have a roster."
)
;
}
Roster
packet
=
new
Roster
(
)
;
if
(
rosterStore
!=
&&
connection
.
isRosterVersioningSupported
(
)
)
{
packet
.
getElement
(
)
.
element
(
"query"
)
.
addAttribute
(
"ver"
,
rosterStore
.
getRosterVersion
(
)
)
;
PacketFilter
filter
=
new
PacketIDFilter
(
packet
.
getID
(
)
)
;
connection
.
addPacketListener
(
new
RosterResultListener
(
)
,
filter
)
;
}
connection
.
sendPacket
(
packet
)
;
}

Reloads the entire roster from the server. This is an asynchronous
operation, which means the method will return immediately, and the roster
will be reloaded at a later point when the server responds to the reload
request.

@throws IllegalStateException
if connection is not logged in or logged in anonymously

Reloads the entire roster from the server . This is an asynchronous operation which means the method will return immediately and the roster will be reloaded at a later point when the server responds to the reload request .


public void createEntry(String user, String name, String[] groups)
            throws XMPPException {
        if (!connection.isAuthenticated()) {
            throw new IllegalStateException("Not logged in to server.");
        }
        if (connection.isAnonymous()) {
            throw new IllegalStateException(
                    "Anonymous users can't have a roster.");
        }

        // Create and send roster entry creation packet.
        Roster rosterPacket = new Roster();
        rosterPacket.setType(IQ.Type.set);
        rosterPacket.addItem(new JID(user), name, null, null,
                Arrays.asList(groups));
        // Wait up to a certain number of seconds for a reply from the server.
        PacketCollector collector = connection
                .createPacketCollector(new PacketIDFilter(rosterPacket.getID()));
        connection.sendPacket(rosterPacket);
        IQ response = (IQ) collector.nextResult(SmackConfiguration
                .getPacketReplyTimeout());
        collector.cancel();
        if (response == null) {
            throw new XMPPException("No response from the server.");
        }
        // If the server replied with an error, throw an exception.
        else if (response.getType() == IQ.Type.error) {
            throw new XMPPException(response.getError());
        }

        // Create a presence subscription packet and send.
        Presence presencePacket = new Presence(Presence.Type.subscribe);
        presencePacket.setTo(user);
        connection.sendPacket(presencePacket);
    }

Creates a new roster entry and presence subscription. The server will
asynchronously update the roster with the subscription status.

@param user
the user. (e.g. johndoe@jabber.org)
@param name
the nickname of the user.
@param groups
the list of group names the entry will belong to, or
<tt>null</tt> if the the roster entry won't belong to a group.
@throws XMPPException
if an XMPP exception occurs.
@throws IllegalStateException
if connection is not logged in or logged in anonymously

Creates a new roster entry and presence subscription . The server will asynchronously update the roster with the subscription status .


public Collection<RosterEntry> getEntries() {
        Set<RosterEntry> allEntries = new HashSet<RosterEntry>();
        // Loop through all roster groups and add their entries to the answer
        for (RosterGroup rosterGroup : getGroups()) {
            allEntries.addAll(rosterGroup.getEntries());
        }
        // Add the roster unfiled entries to the answer
        allEntries.addAll(unfiledEntries);

        return Collections.unmodifiableCollection(allEntries);
    }

Returns an unmodifiable collection of all entries in the roster,
including entries that don't belong to any groups.

@return all entries in the roster.

Returns an unmodifiable collection of all entries in the roster including entries that don t belong to any groups .


public Presence getPresenceResource(String userWithResource) {
        String key = getPresenceMapKey(userWithResource);
        String resource = StringUtils.parseResource(userWithResource);
        Map<String, Presence> userPresences = presenceMap.get(key);
        if (userPresences == null) {
            Presence presence = new Presence(Presence.Type.unavailable);
            presence.setFrom(userWithResource);
            return presence;
        } else {
            Presence presence = userPresences.get(resource);
            if (presence == null) {
                presence = new Presence(Presence.Type.unavailable);
                presence.setFrom(userWithResource);
                return presence;
            } else {
                return presence;
            }
        }
    }

public Presence getPresenceResource ( String userWithResource ) { String key = getPresenceMapKey ( userWithResource ) ; String resource = StringUtils . parseResource ( userWithResource ) ; Map < String , Presence > userPresences = presenceMap . get ( key ) ; if ( userPresences == null ) { Presence presence = new Presence ( Presence . Type . unavailable ) ; presence . setFrom ( userWithResource ) ; return presence ; } else { Presence presence = userPresences . get ( resource ) ; if ( presence == null ) { presence = new Presence ( Presence . Type . unavailable ) ; presence . setFrom ( userWithResource ) ; return presence ; } else { return presence ; } } }

Returns the presence info for a particular user's resource, or
unavailable presence if the user is offline or if no presence information
is available, such as when you are not subscribed to the user's presence
updates.

@param userWithResource
a fully qualified XMPP ID including a resource
(user@domain/resource).
@return the user's current presence, or unavailable presence if the user
is offline or if no presence information is available.

Returns the presence info for a particular user s resource or unavailable presence if the user is offline or if no presence information is available such as when you are not subscribed to the user s presence updates .


private void setOfflinePresences() {
        Presence packetUnavailable;
        for (String user : presenceMap.keySet()) {
            Map<String, Presence> resources = presenceMap.get(user);
            if (resources != null) {
                for (String resource : resources.keySet()) {
                    packetUnavailable = new Presence(Presence.Type.unavailable);
                    packetUnavailable.setFrom(user + "/" + resource);
                    presencePacketListener.processPacket(packetUnavailable);
                }
            }
        }
    }

private void setOfflinePresences ( ) { Presence packetUnavailable ; for ( String user : presenceMap . keySet ( ) ) { Map < String , Presence > resources = presenceMap . get ( user ) ; if ( resources != null ) { for ( String resource : resources . keySet ( ) ) { packetUnavailable = new Presence ( Presence . Type . unavailable ) ; packetUnavailable . setFrom ( user + "/" + resource ) ; presencePacketListener . processPacket ( packetUnavailable ) ; } } } }

Changes the presence of available contacts offline by simulating an
unavailable presence sent from the server. After a disconnection, every
Presence is set to offline.

Changes the presence of available contacts offline by simulating an unavailable presence sent from the server . After a disconnection every Presence is set to offline .


private void fireRosterChangedEvent(Collection<String> addedEntries,
            Collection<String> updatedEntries, Collection<String> deletedEntries) {
        for (RosterListener listener : rosterListeners) {
            if (!addedEntries.isEmpty()) {
                listener.entriesAdded(addedEntries);
            }
            if (!updatedEntries.isEmpty()) {
                listener.entriesUpdated(updatedEntries);
            }
            if (!deletedEntries.isEmpty()) {
                listener.entriesDeleted(deletedEntries);
            }
        }
    }

private void fireRosterChangedEvent ( Collection < String > addedEntries , Collection < String > updatedEntries , Collection < String > deletedEntries ) { for ( RosterListener listener : rosterListeners ) { if ( ! addedEntries . isEmpty ( ) ) { listener . entriesAdded ( addedEntries ) ; } if ( ! updatedEntries . isEmpty ( ) ) { listener . entriesUpdated ( updatedEntries ) ; } if ( ! deletedEntries . isEmpty ( ) ) { listener . entriesDeleted ( deletedEntries ) ; } } }

Fires roster changed event to roster listeners indicating that the
specified collections of contacts have been added, updated or deleted
from the roster.

@param addedEntries
the collection of address of the added contacts.
@param updatedEntries
the collection of address of the updated contacts.
@param deletedEntries
the collection of address of the deleted contacts.

Fires roster changed event to roster listeners indicating that the specified collections of contacts have been added updated or deleted from the roster .


public void setDigest(String connectionID, String password) {
        setDigest(StringUtils.hash(connectionID + password));
    }

public void setDigest ( String connectionID , String password ) { setDigest ( StringUtils . hash ( connectionID + password ) ) ; }

Sets the digest value using a connection ID and password. Password
digests offer a more secure alternative for authentication compared to
plain text. The digest is the hex-encoded SHA-1 hash of the connection ID
plus the user's password. If the digest and password are set, digest
authentication will be used. If only one value is set, the respective
authentication mode will be used.

@param connectionID
the connection ID.
@param password
the password.
@see org.jivesoftware.smack.Connection#getConnectionID()

Sets the digest value using a connection ID and password . Password digests offer a more secure alternative for authentication compared to plain text . The digest is the hex - encoded SHA - 1 hash of the connection ID plus the user s password . If the digest and password are set digest authentication will be used . If only one value is set the respective authentication mode will be used .


@Override
    public Optional<? extends ResourceModel> generateResource(ResourceModel resourceModel, Optional<EventModel> event) {
        switch (resourceModel.getResourceID()) {
            case BroadcasterAvailablePlaylists.RESOURCE_ID: return createBroadcasterAvailablePlaylists();
            case BroadcasterPlaylist.RESOURCE_ID : return createBroadcasterPlaylist(resourceModel);
            default: return MusicResourceGenerator.super.generateResource(resourceModel, event);
        }
    }

@ Override public Optional < ? extends ResourceModel > generateResource ( ResourceModel resourceModel , Optional < EventModel > event ) { switch ( resourceModel . getResourceID ( ) ) { case BroadcasterAvailablePlaylists . RESOURCE_ID : return createBroadcasterAvailablePlaylists ( ) ; case BroadcasterPlaylist . RESOURCE_ID : return createBroadcasterPlaylist ( resourceModel ) ; default : return MusicResourceGenerator . super . generateResource ( resourceModel , event ) ; } }

generates the resources

@param resourceModel the resourceModel
@param event         the Event
@return a Stream containing the resourceModel(s)


static PlayerRequest createPlayerRequest(Playlist playlist, boolean permanent, Identification player, Capabilities capabilities, Context context, Identifiable identifiable) {
        return  new PlayerRequest(null, playlist, permanent, player, capabilities, context, identifiable);
    }

static PlayerRequest createPlayerRequest ( Playlist playlist , boolean permanent , Identification player , Capabilities capabilities , Context context , Identifiable identifiable ) { return new PlayerRequest ( null , playlist , permanent , player , capabilities , context , identifiable ) ; }

helper method for PlaylistSelector
@param playlist the playlist selected
@param permanent the permanent addon
@param player the player
@param capabilities the capabilities
@param context the context
@param identifiable the identifiable
@return a PlayerRequest


@SuppressWarnings("unused")
    public static Optional<Long> getTimePassed(EventModel eventModel) {
        if (eventModel.getListResourceContainer().containsResourcesFromSource(ID)) {
            return eventModel
                    .getListResourceContainer()
                    .provideResource(ID)
                    .stream()
                    .map(ResourceModel::getResource)
                    .filter(ob -> ob instanceof Long)
                    .map(ob -> (Long) ob)
                    .findAny();
        } else {
            return Optional.empty();
        }
    }

@ SuppressWarnings ( "unused" ) public static Optional < Long > getTimePassed ( EventModel eventModel ) { if ( eventModel . getListResourceContainer ( ) . containsResourcesFromSource ( ID ) ) { return eventModel . getListResourceContainer ( ) . provideResource ( ID ) . stream ( ) . map ( ResourceModel :: getResource ) . filter ( ob -> ob instanceof Long ) . map ( ob -> ( Long ) ob ) . findAny ( ) ; } else { return Optional . empty ( ) ; } }

returns the time passed if available
@param eventModel the event
@return the optional long


public void registerUpdateListener(Consumer<PropertiesAssistant> listener) {
        if (listener != null)
            listeners.add(new WeakReference<>(listener));
    }

public void registerUpdateListener ( Consumer < PropertiesAssistant > listener ) { if ( listener != null ) listeners . add ( new WeakReference <> ( listener ) ) ; }

the listener will always be called, when the Properties-file changes.

@param listener the listener

the listener will always be called when the Properties - file changes .


public void initProperties() {
        propertiesPath = getContext().getFiles().getPropertiesLocation() + File.separator
                + getContext().getAddOns().getAddOn().getID() + ".properties";

        this.propertiesFile = new File(propertiesPath);
        if (!this.propertiesFile.exists()) try {
            this.propertiesFile.createNewFile();
        } catch (IOException e) {
            error("Error while trying to create the new Properties file", e);
        }

        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(this.propertiesFile),
                    "UTF8"));
            try {
                properties.load(in);
            } catch (IOException e) {
                error("unable to load the InputStream for the PropertiesFile",e);
            }
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            error("Error while trying to read Properties-File", e);
        }

        if (defaultPropertiesPath != null && new File(defaultPropertiesPath).exists()) {
            @SuppressWarnings("unchecked")
            Enumeration<String> keys = (Enumeration<String>)properties.propertyNames();

            if (!keys.hasMoreElements()) {
                try {
                    createDefaultPropertyFile(defaultPropertiesPath);
                } catch (IOException e) {
                    error("Error while trying to copy the Default-Properties File", e);
                }

                if (new File(defaultPropertiesPath).exists() && !writeToPropertiesFile(defaultPropertiesPath)) return;
                reloadProperties();
            }
        }
    }

Initializes properties in the addOn. Creates new properties file using default properties.

Initializes properties in the addOn . Creates new properties file using default properties .


private void reloadProperties() {
        Properties temp = new Properties();
        BufferedReader bufferedReader = null;
        try {
            File properties = new File(propertiesPath);
            bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(properties), "UTF8"));
            temp.load(bufferedReader);
            this.properties = temp;
            listeners.removeIf(weakReference -> weakReference.get() == null);
            listeners.forEach(weakReference -> {
                Consumer<PropertiesAssistant> consumer = weakReference.get();
                if (consumer != null)
                    consumer.accept(this);
            });
        } catch (IOException e) {
            error("Error while trying to load the Properties-File: "
                    + propertiesPath, e);
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    error("Unable to close input stream", e);
                }
            }
        }
    }

reloads the propertiesFile into the properties object


public static StreamError parseStreamError(Element el) throws IOException,
            XmlPullParserException {
        String code = null;
        Element condEl = (Element) el.elements().iterator().next();
        if (condEl.getNamespace().getURI().equals(StreamError.NAMESPACE)) {
            code = condEl.getName();
        }
        String text = condEl.elementText("text");
        return new StreamError(code, text);
    }

public static StreamError parseStreamError ( Element el ) throws IOException , XmlPullParserException { String code = null ; Element condEl = ( Element ) el . elements ( ) . iterator ( ) . next ( ) ; if ( condEl . getNamespace ( ) . getURI ( ) . equals ( StreamError . NAMESPACE ) ) { code = condEl . getName ( ) ; } String text = condEl . elementText ( "text" ) ; return new StreamError ( code , text ) ; }

Parses stream error packets.

@param doc
the XML parser.
@return an stream error packet.
@throws Exception
if an exception occurs while parsing the packet.


@SuppressWarnings("unchecked")
    public static Collection<String> parseMechanisms(Element mechanismsEl)
            throws Exception {
        List<Element> mechanisms = mechanismsEl.elements("mechanism");
        List<String> mechanismsStr = new LinkedList<String>();
        for (Element mechanismEl : mechanisms) {
            mechanismsStr.add(mechanismEl.getText());
        }
        return mechanismsStr;
    }

@ SuppressWarnings ( "unchecked" ) public static Collection < String > parseMechanisms ( Element mechanismsEl ) throws Exception { List < Element > mechanisms = mechanismsEl . elements ( "mechanism" ) ; List < String > mechanismsStr = new LinkedList < String > ( ) ; for ( Element mechanismEl : mechanisms ) { mechanismsStr . add ( mechanismEl . getText ( ) ) ; } return mechanismsStr ; }

Parse the available SASL mechanisms reported from the server.

@param mechanismsEl
the XML parser, positioned at the start of the mechanisms
stanza.
@return a collection of Stings with the mechanisms included in the
mechanisms stanza.
@throws Exception
if an exception occurs while parsing the stanza.

Parse the available SASL mechanisms reported from the server .


@SuppressWarnings("unchecked")
    public static Collection<String> parseCompressionMethods(
            Element compressionEl) throws IOException, XmlPullParserException {
        List<Element> methodsEls = compressionEl.elements("method");
        List<String> methodsStr = new LinkedList<String>();
        for (Element methodEl : methodsEls) {
            methodsStr.add(methodEl.getText());
        }
        return methodsStr;
    }

@ SuppressWarnings ( "unchecked" ) public static Collection < String > parseCompressionMethods ( Element compressionEl ) throws IOException , XmlPullParserException { List < Element > methodsEls = compressionEl . elements ( "method" ) ; List < String > methodsStr = new LinkedList < String > ( ) ; for ( Element methodEl : methodsEls ) { methodsStr . add ( methodEl . getText ( ) ) ; } return methodsStr ; }

Parse the available compression methods reported from the server.

@param compressionEl
the XML parser, positioned at the start of the compression
stanza.
@return a collection of Stings with the methods included in the
compression stanza.
@throws Exception
if an exception occurs while parsing the stanza.

Parse the available compression methods reported from the server .


public static PacketExtension parsePacketExtension(String elementName,
            String namespace, XmlPullParser parser) throws Exception {
        DefaultPacketExtension extension = new DefaultPacketExtension(
                elementName, namespace);
        boolean done = false;
        while (!done) {
            int eventType = parser.next();
            if (eventType == XmlPullParser.START_TAG) {
                String name = parser.getName();
                // If an empty element, set the value with the empty string.
                if (parser.isEmptyElementTag()) {
                    extension.setValue(name, "");
                }
                // Otherwise, get the the element text.
                else {
                    eventType = parser.next();
                    if (eventType == XmlPullParser.TEXT) {
                        String value = parser.getText();
                        extension.setValue(name, value);
                    }
                }
            } else if (eventType == XmlPullParser.END_TAG) {
                if (parser.getName().equals(elementName)) {
                    done = true;
                }
            }
        }
        return extension;
    }

Parses a packet extension sub-packet.

@param elementName
the XML element name of the packet extension.
@param namespace
the XML namespace of the packet extension.
@param parser
the XML parser, positioned at the starting element of the
extension.
@return a PacketExtension.
@throws Exception
if a parsing error occurs.

Parses a packet extension sub - packet .


private static Object decode(Class<?> type, String value) throws Exception {
        if (type.getName().equals("java.lang.String")) {
            return value;
        }
        if (type.getName().equals("boolean")) {
            return Boolean.valueOf(value);
        }
        if (type.getName().equals("int")) {
            return Integer.valueOf(value);
        }
        if (type.getName().equals("long")) {
            return Long.valueOf(value);
        }
        if (type.getName().equals("float")) {
            return Float.valueOf(value);
        }
        if (type.getName().equals("double")) {
            return Double.valueOf(value);
        }
        if (type.getName().equals("java.lang.Class")) {
            return Class.forName(value);
        }
        return null;
    }

private static Object decode ( Class < ? > type , String value ) throws Exception { if ( type . getName ( ) . equals ( "java.lang.String" ) ) { return value ; } if ( type . getName ( ) . equals ( "boolean" ) ) { return Boolean . valueOf ( value ) ; } if ( type . getName ( ) . equals ( "int" ) ) { return Integer . valueOf ( value ) ; } if ( type . getName ( ) . equals ( "long" ) ) { return Long . valueOf ( value ) ; } if ( type . getName ( ) . equals ( "float" ) ) { return Float . valueOf ( value ) ; } if ( type . getName ( ) . equals ( "double" ) ) { return Double . valueOf ( value ) ; } if ( type . getName ( ) . equals ( "java.lang.Class" ) ) { return Class . forName ( value ) ; } return null ; }

Decodes a String into an object of the specified type. If the object type
is not supported, null will be returned.

@param type
the type of the property.
@param value
the encode String value to decode.
@return the String value decoded into the specified type.
@throws Exception
If decoding failed due to an error.

Decodes a String into an object of the specified type . If the object type is not supported null will be returned .


public static boolean verify(EventModel eventModel, Capabilities capabilities, Identifiable player, List<Identifiable> activators) {
        if (!eventModel.containsDescriptor(StartMusicRequest.ID))
            return false;
        if (!capabilities.handlesPlayRequestFromOutside()) {
            if (activators.stream()
                    .noneMatch(identifiable -> identifiable.isOwner(eventModel.getSource())))
                return false;
        }
        if (!PlaylistResource.getPlaylist(eventModel).map(playlist -> playlist.verify(capabilities)).orElse(true)) {
            return false;
        }
        return SelectorResource.isTarget(eventModel, player)
                .orElse(false);
    }

public static boolean verify ( EventModel eventModel , Capabilities capabilities , Identifiable player , List < Identifiable > activators ) { if ( ! eventModel . containsDescriptor ( StartMusicRequest . ID ) ) return false ; if ( ! capabilities . handlesPlayRequestFromOutside ( ) ) { if ( activators . stream ( ) . noneMatch ( identifiable -> identifiable . isOwner ( eventModel . getSource ( ) ) ) ) return false ; } if ( ! PlaylistResource . getPlaylist ( eventModel ) . map ( playlist -> playlist . verify ( capabilities ) ) . orElse ( true ) ) { return false ; } return SelectorResource . isTarget ( eventModel , player ) . orElse ( false ) ; }

verifies that the StartMusicRequest is correct and checks whether the you are meant to react to it
@param eventModel the EventModel to check against
@param player the identifiable
@param capabilities the capabilities
@param activators the activators which are able to start the player if it is not able to start from outside commands
@return true if verified, false if not


public static Optional<PlaybackState> getPlaybackStateFromResource(ResourceModel x) {
        if (!x.getResourceID().equals(ID))
            return Optional.empty();
        Object resource = x.getResource();
        if (resource instanceof String) {
            String state = (String) resource;
            try {
                return Optional.of(PlaybackState.valueOf(state));
            } catch (IllegalArgumentException e) {
                return Optional.empty();
            }
        } else {
            return Optional.empty();
        }
    }

public static Optional < PlaybackState > getPlaybackStateFromResource ( ResourceModel x ) { if ( ! x . getResourceID ( ) . equals ( ID ) ) return Optional . empty ( ) ; Object resource = x . getResource ( ) ; if ( resource instanceof String ) { String state = ( String ) resource ; try { return Optional . of ( PlaybackState . valueOf ( state ) ) ; } catch ( IllegalArgumentException e ) { return Optional . empty ( ) ; } } else { return Optional . empty ( ) ; } }

returns the PlaybackState from the resource
@param x the resourceModel
@return the optional Playbackstate (empty if illegal resource)


public String getSecretKey(String subdomain) {
        // Find the proper secret key to connect as the subdomain.
        String secretKey = secretKeys.get(subdomain);
        if (secretKey == null) {
            secretKey = defaultSecretKey;
        }
        return secretKey;
    }

Returns the secret key for a sub-domain. If no key was found then the
default secret key will be returned.

@param subdomain
the subdomain to return its secret key.
@return the secret key for a sub-domain.

Returns the secret key for a sub - domain . If no key was found then the default secret key will be returned .


public boolean isMultipleAllowed(String subdomain) {
        Boolean allowed = allowMultiple.get(subdomain);
        return allowed != null && allowed;
    }

public boolean isMultipleAllowed ( String subdomain ) { Boolean allowed = allowMultiple . get ( subdomain ) ; return allowed != null && allowed ; }

Returns if we want components to be able to connect multiple times to the
same JID. This is a custom Openfire extension and will not work with any
other XMPP server. Other XMPP servers should ignore this extra setting.

@param subdomain
the sub-domain.
@return True or false if we are allowing multiple connections.

Returns if we want components to be able to connect multiple times to the same JID . This is a custom Openfire extension and will not work with any other XMPP server . Other XMPP servers should ignore this extra setting .


public V put(K key, V value) {
        if (key == null) {
            throw new NullPointerException("null keys not allowed");
        }
        if (value == null) {
            throw new NullPointerException("null values not allowed");
        }

        purgeBeforeWrite();
        return super.put(key, value);
    }

public
V
put
(
K
key
,
V
value
)
{
if
(
key
==
)
{
throw
new
NullPointerException
(
"null keys not allowed"
)
;
}
if
(
value
==
)
{
throw
new
NullPointerException
(
"null values not allowed"
)
;
}
purgeBeforeWrite
(
)
;
return
super
.
put
(
key
,
value
)
;
}

Puts a key-value mapping into this map. Neither the key nor the value may
be null.

@param key
the key to add, must not be null
@param value
the value to add, must not be null
@return the value previously mapped to this key, null if none
@throws NullPointerException
if either the key or value is null

Puts a key - value mapping into this map . Neither the key nor the value may be null .


public Set<K> keySet() {
        if (keySet == null) {
            keySet = new ReferenceKeySet<K, V>(this);
        }
        return keySet;
    }

public Set < K > keySet ( ) { if ( keySet == null ) { keySet = new ReferenceKeySet < K , V > ( this ) ; } return keySet ; }

Returns a set view of this map's keys.

@return a set view of this map's keys


public Collection<V> values() {
        if (values == null) {
            values = new ReferenceValues<K, V>(this);
        }
        return values;
    }

public Collection < V > values ( ) { if ( values == null ) { values = new ReferenceValues < K , V > ( this ) ; } return values ; }

Returns a collection view of this map's values.

@return a set view of this map's values

Returns a collection view of this map s values .


protected void purge(Reference ref) {
        // The hashCode of the reference is the hashCode of the
        // mapping key, even if the reference refers to the
        // mapping value...
        int hash = ref.hashCode();
        int index = hashIndex(hash, data.length);
        HashEntry<K, V> previous = null;
        HashEntry<K, V> entry = data[index];
        while (entry != null) {
            if (((ReferenceEntry<K, V>) entry).purge(ref)) {
                if (previous == null) {
                    data[index] = entry.next;
                } else {
                    previous.next = entry.next;
                }
                this.size--;
                return;
            }
            previous = entry;
            entry = entry.next;
        }

    }

Purges the specified reference.

@param ref
the reference to purge


protected HashEntry<K, V> getEntry(Object key) {
        if (key == null) {
            return null;
        } else {
            return super.getEntry(key);
        }
    }

protected HashEntry < K , V > getEntry ( Object key ) { if ( key == null ) { return null ; } else { return super . getEntry ( key ) ; } }

Gets the entry mapped to the key specified.

@param key
the key
@return the entry, null if no match

Gets the entry mapped to the key specified .


protected int hashEntry(Object key, Object value) {
        return (key == null ? 0 : key.hashCode())
                ^ (value == null ? 0 : value.hashCode());
    }

protected int hashEntry ( Object key , Object value ) { return ( key == null ? 0 : key . hashCode ( ) ) ^ ( value == null ? 0 : value . hashCode ( ) ) ; }

Gets the hash code for a MapEntry. Subclasses can override this, for
example to use the identityHashCode.

@param key
the key to get a hash code for, may be null
@param value
the value to get a hash code for, may be null
@return the hash code, as per the MapEntry specification

Gets the hash code for a MapEntry . Subclasses can override this for example to use the identityHashCode .


public HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode,
            K key, V value) {
        return new ReferenceEntry<K, V>(this, (ReferenceEntry<K, V>) next,
                hashCode, key, value);
    }

public HashEntry < K , V > createEntry ( HashEntry < K , V > next , int hashCode , K key , V value ) { return new ReferenceEntry < K , V > ( this , ( ReferenceEntry < K , V > ) next , hashCode , key , value ) ; }

Creates a ReferenceEntry instead of a HashEntry.

@param next
the next entry in sequence
@param hashCode
the hash code to use
@param key
the key to store
@param value
the value to store
@return the newly created entry

Creates a ReferenceEntry instead of a HashEntry .


@Override
    public boolean controlEvents(EventModel eventModel) {
        if (level.compareTo(PresenceIndicatorLevel.WEAK) >= 0) {
            return present;
        } else //noinspection SimplifiableIfStatement
            if (level.compareTo(PresenceIndicatorLevel.WEAK) < 0 && mostVague.get()) {
            return present;
        } else {
            return true;
        }
    }

@
Override
public
boolean
controlEvents
(
EventModel
eventModel
)
{
if
(
level
.
compareTo
(
PresenceIndicatorLevel
.
WEAK
)
>=
0
)
{
return
present
;
}
else
//noinspection SimplifiableIfStatement
if
(
level
.
compareTo
(
PresenceIndicatorLevel
.
WEAK
)
<
0
&&
mostVague
.
get
(
)
)
{
return
present
;
}
else
{
return
true
;
}
}

Controls whether the fired Event should be dispatched to all the listeners. This method should execute quickly

@param eventModel the Event
@return true if it should dispatch, false if not

Controls whether the fired Event should be dispatched to all the listeners . This method should execute quickly


public void setPresence(boolean present) {
        if (this.present == present)
            return;
        this.present = present;
        updateVague();
        if (present) {
            firePresence(true);
        } else {
            fireLeaving();
        }
    }

public void setPresence ( boolean present ) { if ( this . present == present ) return ; this . present = present ; updateVague ( ) ; if ( present ) { firePresence ( true ) ; } else { fireLeaving ( ) ; } }

sets the presence
@param present true for presence, false if not


private void updateVague() {
        generateResource(PresenceResource.ID)
            .orElse(CompletableFuture.completedFuture(new ArrayList<>()))
            .thenAccept(list -> mostVague.set(list.stream()
                            .map(Presence::importPresence)
                            .filter(Optional::isPresent)
                            .map(Optional::get)
                            .map(Presence::getLevel)
                            .noneMatch(level -> level.compareTo(getLevel()) > 0))
            );
    }

private void updateVague ( ) { generateResource ( PresenceResource . ID ) . orElse ( CompletableFuture . completedFuture ( new ArrayList <> ( ) ) ) . thenAccept ( list -> mostVague . set ( list . stream ( ) . map ( Presence :: importPresence ) . filter ( Optional :: isPresent ) . map ( Optional :: get ) . map ( Presence :: getLevel ) . noneMatch ( level -> level . compareTo ( getLevel ( ) ) > 0 ) ) ) ; }

updates the boolean whether it is the mode vague


void deliver(Message message) {
        // Because the collector and listeners are expecting a thread ID with
        // a specific value, set the thread ID on the message even though it
        // probably never had one.
        message.setThread(threadID);

        for (MessageListener listener : listeners) {
            listener.processMessage(this, message);
        }
    }

Delivers a message directly to this chat, which will add the message to
the collector and deliver it to all listeners registered with the Chat.
This is used by the Connection class to deliver messages without a thread
ID.

@param message
the message.

Delivers a message directly to this chat which will add the message to the collector and deliver it to all listeners registered with the Chat . This is used by the Connection class to deliver messages without a thread ID .


protected final ST generateScript(String clazz, HashMap<String, Boolean> targetMap){
		ST ret = this.stg.getInstanceOf("generateExec");
		ret.add("target", targetMap);
		ret.add("applicationHome", this.applicationDir);
		ret.add("runName", this.configuration.get(PROP_RUN_SCRIPT_NAME));
		ret.add("class", clazz);
		return ret;
	}

protected final ST generateScript ( String clazz , HashMap < String , Boolean > targetMap ) { ST ret = this . stg . getInstanceOf ( "generateExec" ) ; ret . add ( "target" , targetMap ) ; ret . add ( "applicationHome" , this . applicationDir ) ; ret . add ( "runName" , this . configuration . get ( PROP_RUN_SCRIPT_NAME ) ) ; ret . add ( "class" , clazz ) ; return ret ; }

Generates a script.
@param clazz the class for the script
@param targetMap map for targets
@return the final template for the script


protected final int initOutputDir(){
		String parent = System.getProperty("user.dir");
		String target = parent + File.separator + this.target;
		File targetDir = new File(target);
		File parentDir = targetDir.getParentFile();

		if(targetDir.exists()){
			//target dir exists, let's see if it is what we want it to be
			if(!targetDir.isDirectory()){
				System.err.println(this.getAppName() + ": target dir <" + target + "> exists but is not a directory, exiting");
				return -1;
			}
			if(!targetDir.canWrite()){
				System.err.println(this.getAppName() + ": target dir <" + target + "> exists but but cannot write into it, exiting");
				return -1;
			}
		}
		else{
			//target dir does not exist, let's see if we can create it the way we need
			if(!parentDir.isDirectory()){
				System.err.println(this.getAppName() + ": target dir parent <" + parent + "> exists but is not a directory, exiting");
				return -1;
			}
			if(!parentDir.canWrite()){
				System.err.println(this.getAppName() + ": target dir parent <" + parent + "> exists but but cannot write into it, exiting");
				return -1;
			}

			if(!targetDir.mkdir()){
				System.err.println(this.getAppName() + ": could not create target dir <" + target + ">, exiting");
				return -1;
			}
		}

		this.outputDir = target;
		return 0;
	}

Tests and if necessary creates an output directory.
The root path is the current directory as given by the system property "user.dir".
The created output directory has the name of the specified target for the generator.
The method fails if the output directory cannot be created or if it exists and is write protected.
@return 0 on success with configuration loaded, -1 on error with errors printed on standard error

Tests and if necessary creates an output directory . The root path is the current directory as given by the system property user . dir . The created output directory has the name of the specified target for the generator . The method fails if the output directory cannot be created or if it exists and is write protected .


protected final Properties loadProperties(String filename){
		Properties ret = new Properties();

		URL url = null;
		File f = new File(filename.toString());
		if(f.exists()){
			try{
				url = f.toURI().toURL();
			}
			catch(Exception ignore){}
		}
		else{
			ClassLoader loader = Thread.currentThread().getContextClassLoader();
			url = loader.getResource(filename);
			if(url==null){
				loader = Gen_RunScripts.class.getClassLoader();
				url = loader.getResource(filename);
			}
		}

		try{
			ret.load(url.openStream());
		}
		catch (IOException e){
			System.err.println(this.getAppName() + ": cannot load property file <" + filename + ">, IO exception\n--><" + e + ">");
		}
		catch (Exception e){
			System.err.println(this.getAppName() + ": cannot load property file <" + filename + ">, general exception\n--><" + e + ">");
		}
		return ret;
	}

protected
final
Properties
loadProperties
(
String
filename
)
{
Properties
ret
=
new
Properties
(
)
;
URL
url
=
;
File
f
=
new
File
(
filename
.
toString
(
)
)
;
if
(
f
.
exists
(
)
)
{
try
{
url
=
f
.
toURI
(
)
.
toURL
(
)
;
}
catch
(
Exception
ignore
)
{
}
}
else
{
ClassLoader
loader
=
Thread
.
currentThread
(
)
.
getContextClassLoader
(
)
;
url
=
loader
.
getResource
(
filename
)
;
if
(
url
==
)
{
loader
=
Gen_RunScripts
.
class
.
getClassLoader
(
)
;
url
=
loader
.
getResource
(
filename
)
;
}
}
try
{
ret
.
load
(
url
.
openStream
(
)
)
;
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
this
.
getAppName
(
)
+
": cannot load property file <"
+
filename
+
">, IO exception\n--><"
+
e
+
">"
)
;
}
catch
(
Exception
e
)
{
System
.
err
.
println
(
this
.
getAppName
(
)
+
": cannot load property file <"
+
filename
+
">, general exception\n--><"
+
e
+
">"
)
;
}
return
ret
;
}

Loads properties from a file.
@param filename property file loaded from class path or file system
@return loaded properties, null if nothing could be loaded plus error messages to standard error if exceptions are caught


protected final int writeFile(String fn, ST st){
		try {
			FileWriter fs = new FileWriter(fn);
			BufferedWriter bw = new BufferedWriter(fs);
			bw.write(st.render());
			bw.close();
		}
		catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

protected final int writeFile ( String fn , ST st ) { try { FileWriter fs = new FileWriter ( fn ) ; BufferedWriter bw = new BufferedWriter ( fs ) ; bw . write ( st . render ( ) ) ; bw . close ( ) ; } catch ( IOException e ) { e . printStackTrace ( ) ; return - 1 ; } return 0 ; }

Writes an ST object to a file.
@param fn file name
@param st ST template
@return 0 on success with configuration loaded, -1 on error with errors printed on standard error


public static Optional<Progress> getProgress(EventModel eventModel) {
        if (eventModel.getListResourceContainer().containsResourcesFromSource(ID)) {
            return eventModel
                    .getListResourceContainer()
                    .provideResource(ID)
                    .stream()
                    .findAny()
                    .flatMap(Progress::importResource);

        } else {
            return Optional.empty();
        }
    }

public static Optional < Progress > getProgress ( EventModel eventModel ) { if ( eventModel . getListResourceContainer ( ) . containsResourcesFromSource ( ID ) ) { return eventModel . getListResourceContainer ( ) . provideResource ( ID ) . stream ( ) . findAny ( ) . flatMap ( Progress :: importResource ) ; } else { return Optional . empty ( ) ; } }

gets the first Progress if found in the EventModel
@param eventModel the EventModel
@return return the optional Progress


public static <E> Collection<E> decorate(Collection<E> coll) {
        return new SynchronizedCollection<E>(coll);
    }

public static < E > Collection < E > decorate ( Collection < E > coll ) { return new SynchronizedCollection < E > ( coll ) ; }

Factory method to create a synchronized collection.

@param coll  the collection to decorate, must not be null
@throws IllegalArgumentException if collection is null

Factory method to create a synchronized collection .


public static Collection<ServiceResolver> discover(InetAddress start, int count, int msTimeout) {
    Collection<ServiceResolver> result = new ArrayList<ServiceResolver>();
    Collection<InetAddress> hosts = IPv4Scanner.scanRange(start, count, msTimeout);
    for (InetAddress host: hosts) {
      ServiceResolver resolver = new ServiceResolver(host);
      logger.info("resolving {} {}", host.getHostAddress(), host.getCanonicalHostName());
      JSONResult config = resolver.getConfig();
      if (config != null) {
         result.add(resolver);
      }
    }

    return result;
  }

public
static
Collection
<
ServiceResolver
>
discover
(
InetAddress
start
,
int
count
,
int
msTimeout
)
{
Collection
<
ServiceResolver
>
result
=
new
ArrayList
<
ServiceResolver
>
(
)
;
Collection
<
InetAddress
>
hosts
=
IPv4Scanner
.
scanRange
(
start
,
count
,
msTimeout
)
;
for
(
InetAddress
host
:
hosts
)
{
ServiceResolver
resolver
=
new
ServiceResolver
(
host
)
;
logger
.
info
(
"resolving {} {}"
,
host
.
getHostAddress
(
)
,
host
.
getCanonicalHostName
(
)
)
;
JSONResult
config
=
resolver
.
getConfig
(
)
;
if
(
config
!=
)
{
result
.
add
(
resolver
)
;
}
}
return
result
;
}

Discover FireREST services located in a range of IPv4 InetAddresses.
E.g., The range of 256 addresses that starts with 10.0.1.128 ends with 10.0.2.127.

@param start first InetAddress to scan (null for localhost)
@param count number of subsequent InetAddresses in the range
@param msTimeout maximum time to wait for host response
@return ServiceResolvers that resolve to a FireREST service.

Discover FireREST services located in a range of IPv4 InetAddresses . E . g . The range of 256 addresses that starts with 10 . 0 . 1 . 128 ends with 10 . 0 . 2 . 127 .


public JSONResult getConfig() {
    if (attempts == 0) {
      try {
	resolve();
      } catch(Exception e) {
        // discard exception
      }
    }
    if (config == null) {
      logger.info("{} => no response", url);
      return null;
    }

    logger.info("{} => {}", url, config.get("FireREST").getString());
    return config;
  }

public
JSONResult
getConfig
(
)
{
if
(
attempts
==
0
)
{
try
{
resolve
(
)
;
}
catch
(
Exception
e
)
{
// discard exception
}
}
if
(
config
==
)
{
logger
.
info
(
"{} => no response"
,
url
)
;
return
;
}
logger
.
info
(
"{} => {}"
,
url
,
config
.
get
(
"FireREST"
)
.
getString
(
)
)
;
return
config
;
}

Return the cached service configuration, resolving the service if required.

@return service configuration or null if service could not be resolved.

Return the cached service configuration resolving the service if required .


@Override
    public org.intellimate.izou.sdk.specification.context.ThreadPool getThreadPool() {
        return threadPool;
    }

@ Override public org . intellimate . izou . sdk . specification . context . ThreadPool getThreadPool ( ) { return threadPool ; }

returns the API used to manage the ThreadPool

@return ThreadPool


public static Optional<StopMusic> createStopMusic(Identification source, Identification target) {
        if (target == null || target.equals(source))
            return Optional.empty();
        try {
            StopMusic stopRequest = new StopMusic(source);
            stopRequest.addResource(new SelectorResource(source, target));
            return Optional.of(stopRequest);
        } catch (IllegalArgumentException e) {
            return Optional.empty();
        }
    }

public static Optional < StopMusic > createStopMusic ( Identification source , Identification target ) { if ( target == null || target . equals ( source ) ) return Optional . empty ( ) ; try { StopMusic stopRequest = new StopMusic ( source ) ; stopRequest . addResource ( new SelectorResource ( source , target ) ) ; return Optional . of ( stopRequest ) ; } catch ( IllegalArgumentException e ) { return Optional . empty ( ) ; } }

creates a new StopRequest
@param source the caller
@param target the target who should start playing
@return the optional StopMusicRequest


public static boolean verify(EventModel eventModel, Identifiable player) {
        if (!eventModel.containsDescriptor(StopMusic.ID))
            return false;
        return SelectorResource.isTarget(eventModel, player)
                .orElse(true);
    }

public static boolean verify ( EventModel eventModel , Identifiable player ) { if ( ! eventModel . containsDescriptor ( StopMusic . ID ) ) return false ; return SelectorResource . isTarget ( eventModel , player ) . orElse ( true ) ; }

verifies that the StopMusicRequest is correct and checks whether the you are meant to react to it
@param eventModel the EventModel to check against
@param player the identifiable
@return true if verified, false if not


public DseCluster getCluster(String hostsAndPorts, String username, String password,
            String authorizationId) {
        return getCluster(
                ClusterIdentifier.getInstance(hostsAndPorts, username, password, authorizationId));
    }

public DseCluster getCluster ( String hostsAndPorts , String username , String password , String authorizationId ) { return getCluster ( ClusterIdentifier . getInstance ( hostsAndPorts , username , password , authorizationId ) ) ; }

Obtain a DSE cluster instance.

@param hostsAndPorts
format: "host1:port1,host2,host3:port3". If no port is
specified, the {@link CqlUtils#DEFAULT_CASSANDRA_PORT} is used.
@param username
@param password
@param authorizationId
DSE allows a user to connect as another user or role, provide the name of the
user/role you want to connect as via this parameter
@return


public void addConnectionListener(ConnectionListener connectionListener) {
        if (connectionListener == null) {
            return;
        }
        if (!connectionListeners.contains(connectionListener)) {
            connectionListeners.add(connectionListener);
        }
    }

public void addConnectionListener ( ConnectionListener connectionListener ) { if ( connectionListener == null ) { return ; } if ( ! connectionListeners . contains ( connectionListener ) ) { connectionListeners . add ( connectionListener ) ; } }

Adds a connection listener to this connection that will be notified when
the connection closes or fails.

@param connectionListener
a connection listener.

Adds a connection listener to this connection that will be notified when the connection closes or fails .


public void addPacketListener(PacketListener packetListener,
            PacketFilter packetFilter) {
        if (packetListener == null) {
            throw new NullPointerException("Packet listener is null.");
        }
        ListenerWrapper wrapper = new ListenerWrapper(packetListener,
                packetFilter);
        recvListeners.put(packetListener, wrapper);
    }

public
void
addPacketListener
(
PacketListener
packetListener
,
PacketFilter
packetFilter
)
{
if
(
packetListener
==
)
{
throw
new
NullPointerException
(
"Packet listener is null."
)
;
}
ListenerWrapper
wrapper
=
new
ListenerWrapper
(
packetListener
,
packetFilter
)
;
recvListeners
.
put
(
packetListener
,
wrapper
)
;
}

Registers a packet listener with this connection. A packet listener will
be invoked only when an incoming packet is received. A packet filter
determines which packets will be delivered to the listener. If the same
packet listener is added again with a different filter, only the new
filter will be used.

<p>
NOTE: If you want get a similar callback for outgoing packets, see
{@link #addPacketInterceptor(PacketInterceptor, PacketFilter)}.

@param packetListener
the packet listener to notify of new received packets.
@param packetFilter
the packet filter to use.

Registers a packet listener with this connection . A packet listener will be invoked only when an incoming packet is received . A packet filter determines which packets will be delivered to the listener . If the same packet listener is added again with a different filter only the new filter will be used .


public void addPacketSendingListener(PacketListener packetListener,
            PacketFilter packetFilter) {
        if (packetListener == null) {
            throw new NullPointerException("Packet listener is null.");
        }
        ListenerWrapper wrapper = new ListenerWrapper(packetListener,
                packetFilter);
        sendListeners.put(packetListener, wrapper);
    }

public
void
addPacketSendingListener
(
PacketListener
packetListener
,
PacketFilter
packetFilter
)
{
if
(
packetListener
==
)
{
throw
new
NullPointerException
(
"Packet listener is null."
)
;
}
ListenerWrapper
wrapper
=
new
ListenerWrapper
(
packetListener
,
packetFilter
)
;
sendListeners
.
put
(
packetListener
,
wrapper
)
;
}

Registers a packet listener with this connection. The listener will be
notified of every packet that this connection sends. A packet filter
determines which packets will be delivered to the listener. Note that the
thread that writes packets will be used to invoke the listeners.
Therefore, each packet listener should complete all operations quickly or
use a different thread for processing.

@param packetListener
the packet listener to notify of sent packets.
@param packetFilter
the packet filter to use.

Registers a packet listener with this connection . The listener will be notified of every packet that this connection sends . A packet filter determines which packets will be delivered to the listener . Note that the thread that writes packets will be used to invoke the listeners . Therefore each packet listener should complete all operations quickly or use a different thread for processing .


protected void firePacketSendingListeners(Packet packet) {
        // Notify the listeners of the new sent packet
        for (ListenerWrapper listenerWrapper : sendListeners.values()) {
            listenerWrapper.notifyListener(packet);
        }
    }

Process all packet listeners for sending packets.

@param packet
the packet to process.

Process all packet listeners for sending packets .


public void addPacketInterceptor(PacketInterceptor packetInterceptor,
            PacketFilter packetFilter) {
        if (packetInterceptor == null) {
            throw new NullPointerException("Packet interceptor is null.");
        }
        interceptors.put(packetInterceptor, new InterceptorWrapper(
                packetInterceptor, packetFilter));
    }

public
void
addPacketInterceptor
(
PacketInterceptor
packetInterceptor
,
PacketFilter
packetFilter
)
{
if
(
packetInterceptor
==
)
{
throw
new
NullPointerException
(
"Packet interceptor is null."
)
;
}
interceptors
.
put
(
packetInterceptor
,
new
InterceptorWrapper
(
packetInterceptor
,
packetFilter
)
)
;
}

Registers a packet interceptor with this connection. The interceptor will
be invoked every time a packet is about to be sent by this connection.
Interceptors may modify the packet to be sent. A packet filter determines
which packets will be delivered to the interceptor.

<p>
NOTE: For a similar functionality on incoming packets, see
{@link #addPacketListener(PacketListener, PacketFilter)}.

@param packetInterceptor
the packet interceptor to notify of packets about to be sent.
@param packetFilter
the packet filter to use.

Registers a packet interceptor with this connection . The interceptor will be invoked every time a packet is about to be sent by this connection . Interceptors may modify the packet to be sent . A packet filter determines which packets will be delivered to the interceptor .


protected void firePacketInterceptors(Packet packet) {
        if (packet != null) {
            for (InterceptorWrapper interceptorWrapper : interceptors.values()) {
                interceptorWrapper.notifyListener(packet);
            }
        }
    }

protected void firePacketInterceptors ( Packet packet ) { if ( packet != null ) { for ( InterceptorWrapper interceptorWrapper : interceptors . values ( ) ) { interceptorWrapper . notifyListener ( packet ) ; } } }

Process interceptors. Interceptors may modify the packet that is about to
be sent. Since the thread that requested to send the packet will invoke
all interceptors, it is important that interceptors perform their work as
soon as possible so that the thread does not remain blocked for a long
period.

@param packet
the packet that is going to be sent to the server

Process interceptors . Interceptors may modify the packet that is about to be sent . Since the thread that requested to send the packet will invoke all interceptors it is important that interceptors perform their work as soon as possible so that the thread does not remain blocked for a long period .


public static Object toValue(String name, Object value) {
		String[] parts = StringUtils.split(name, "@", 2);
		String fieldName = null;
		String fieldType = "String";
		if (parts.length == 2) {
			fieldType = parts[1];
			fieldName = parts[0];
		} else if (parts.length == 1) {
			fieldName = parts[0];
		} else {
			throw new IllegalArgumentException("Invalid property name");
		}
		try {
			int l = Array.getLength(value);
			RequestParameterType<?> rpt = TYPES.get(fieldType);
			if (rpt == null) {
				rpt = TYPES.get(RequestParameterType.STRING);
			}
			if (!fieldName.endsWith("[]") && l == 1) {
				return rpt.newInstance(Array.get(value, 0));
			}
			Class<?> componentType = rpt.getComponentType();
			Object[] a = (Object[]) Array.newInstance(componentType, l);
			for (int i = 0; i < l; i++) {
				a[i] = rpt.newInstance(Array.get(value, i));
			}
			return a;
		} catch (IllegalArgumentException e) {
			RequestParameterType<?> rpt = TYPES.get(fieldType);
			if (rpt == null) {
				rpt = TYPES.get(RequestParameterType.STRING);
			}
			return rpt.newInstance(value);
		}
	}

public
static
Object
toValue
(
String
name
,
Object
value
)
{
String
[
]
parts
=
StringUtils
.
split
(
name
,
"@"
,
2
)
;
String
fieldName
=
;
String
fieldType
=
"String"
;
if
(
parts
.
length
==
2
)
{
fieldType
=
parts
[
1
]
;
fieldName
=
parts
[
0
]
;
}
else
if
(
parts
.
length
==
1
)
{
fieldName
=
parts
[
0
]
;
}
else
{
throw
new
IllegalArgumentException
(
"Invalid property name"
)
;
}
try
{
int
l
=
Array
.
getLength
(
value
)
;
RequestParameterType
<
>
rpt
=
TYPES
.
get
(
fieldType
)
;
if
(
rpt
==
)
{
rpt
=
TYPES
.
get
(
RequestParameterType
.
STRING
)
;
}
if
(
!
fieldName
.
endsWith
(
"[]"
)
&&
l
==
1
)
{
return
rpt
.
newInstance
(
Array
.
get
(
value
,
0
)
)
;
}
Class
<
>
componentType
=
rpt
.
getComponentType
(
)
;
Object
[
]
a
=
(
Object
[
]
)
Array
.
newInstance
(
componentType
,
l
)
;
for
(
int
i
=
0
;
i
<
l
;
i
++
)
{
a
[
i
]
=
rpt
.
newInstance
(
Array
.
get
(
value
,
i
)
)
;
}
return
a
;
}
catch
(
IllegalArgumentException
e
)
{
RequestParameterType
<
>
rpt
=
TYPES
.
get
(
fieldType
)
;
if
(
rpt
==
)
{
rpt
=
TYPES
.
get
(
RequestParameterType
.
STRING
)
;
}
return
rpt
.
newInstance
(
value
)
;
}
}

Creates the most suitable type.

@param name
the name. Types are specified as name@Type where Type is the
name of the type. If the name ends with a [] the type is
forced to be an array.
@param value
the value the value. If its an array, the type is assumed to
be an array provided there is more than one element. If there
is one element and the name ends with [] an array is created,
otherwise a scalar is created.
@return an instance


public void connectionLost() {
        // Ensure that only one thread will try to reconnect.
        synchronized (this) {
            if (reconnecting) {
                return;
            }
            reconnecting = true;
        }
        readerThread = null;
        boolean isConnected = false;
        if (!shutdown) {
            // Notify the component that connection was lost so it needs to
            // shutdown. The component is
            // still registered in the local component manager but just not
            // connected to the server
            component.shutdown();
        }
        while (!isConnected && !shutdown) {
            try {
                connect(host, port, subdomain);
                isConnected = true;
                // It may be possible that while a new connection was being
                // established the
                // component was required to shutdown so in this case we need to
                // close the new
                // connection
                if (shutdown) {
                    disconnect();
                } else {
                    // Component is back again working so start it up again
                    start();
                }
            } catch (ComponentException e) {
                manager.getLog().error(
                        "Error trying to reconnect with the server", e);
                // Wait for 5 seconds until the next retry
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    // Do nothing
                }
            }
        }
        reconnecting = false;
    }

Notification message that the connection with the server was lost
unexpectedly. We will try to reestablish the connection for ever until
the connection has been reestablished or this thread has been stopped.

Notification message that the connection with the server was lost unexpectedly . We will try to reestablish the connection for ever until the connection has been reestablished or this thread has been stopped .


protected String getCurrentThreadId() {

        String attach_id = (String)ThreadSession.getValue(getThreadSessionKey());
        if (attach_id != null)
            return attach_id;

        Thread thread = Thread.currentThread();
        return thread.toString() + "(" + thread.hashCode() + ")";
    }

protected String getCurrentThreadId ( ) { String attach_id = ( String ) ThreadSession . getValue ( getThreadSessionKey ( ) ) ; if ( attach_id != null ) return attach_id ; Thread thread = Thread . currentThread ( ) ; return thread . toString ( ) + "(" + thread . hashCode ( ) + ")" ; }

Retrieve the current thread id for use by the
transaction code.

@return the thread id of the current thread

Retrieve the current thread id for use by the transaction code .


private boolean validNode(final Node<K,V> node, final String thread_id) {
        if (auto_commit || node == null)
            return (node != null);

        return !((node.is(Node.DELETED, thread_id)) ||
                   (node.is(Node.ADDED, null) && node.is(Node.NO_CHANGE, thread_id)));
    }

private boolean validNode ( final Node < K , V > node , final String thread_id ) { if ( auto_commit || node == null ) return ( node != null ) ; return ! ( ( node . is ( Node . DELETED , thread_id ) ) || ( node . is ( Node . ADDED , null ) && node . is ( Node . NO_CHANGE , thread_id ) ) ) ; }

Checks that this node is valid for the current thread

@param node the node to be checked

@return true if node is valid, otherwise false


public K getKeyForValue(final Object value)
            throws ClassCastException, NullPointerException {
        return (K)doGet(value, VALUE);
    }

public K getKeyForValue ( final Object value ) throws ClassCastException , NullPointerException { return ( K ) doGet ( value , VALUE ) ; }

Returns the key to which this map maps the specified value.
Returns null if the map contains no mapping for this value.

@param value value whose associated key is to be returned.

@return the key to which this map maps the specified value, or
null if the map contains no mapping for this value.

@throws ClassCastException if the value is of an
inappropriate type for this map.
@throws NullPointerException if the value is null

Returns the key to which this map maps the specified value . Returns null if the map contains no mapping for this value .


private Object doGet(final Object o, final int index) {

        checkNonNullComparable(o, index);

        Node<K,V> node = lookupValid(o, index, getCurrentThreadId());

        return (node==null)
                ? null
                : node.getData(oppositeIndex(index));
    }

private Object doGet ( final Object o , final int index ) { checkNonNullComparable ( o , index ) ; Node < K , V > node = lookupValid ( o , index , getCurrentThreadId ( ) ) ; return ( node == null ) ? null : node . getData ( oppositeIndex ( index ) ) ; }

common get logic, used to get by key or get by value

@param o the key or value that we're looking for
@param index KEY or VALUE

@return the key (if the value was mapped) or the value (if the
key was mapped); null if we couldn't find the specified
object

common get logic used to get by key or get by value


private Node<K,V> lookupValid(final Object data, final int index, final String thread_id) {
        return nextEqualValid(getFloorEqualNode(lookup(data, index), index), index, thread_id);
    }

private Node < K , V > lookupValid ( final Object data , final int index , final String thread_id ) { return nextEqualValid ( getFloorEqualNode ( lookup ( data , index ) , index ) , index , thread_id ) ; }

do the actual lookup of a piece of valid data

@param data the key or value to be looked up
@param index KEY or VALUE

@return the desired Node, or null if there is no mapping of the
specified data


private Node<K,V> lookup(final Object data, final int index) {

        Node<K,V> rval = null;
        Node<K,V> node = rootNode[index];

        while (node != null) {
            int cmp = compare(Node.NO_CHANGE, data, node.getStatus(), node.getData(index), index);

            if (cmp == 0) {
                rval = node;

                break;
            } else {
                node = (cmp < 0)
                       ? node.getLeft(index)
                       : node.getRight(index);
            }
        }

        return rval;
    }

private Node < K , V > lookup ( final Object data , final int index ) { Node < K , V > rval = null ; Node < K , V > node = rootNode [ index ] ; while ( node != null ) { int cmp = compare ( Node . NO_CHANGE , data , node . getStatus ( ) , node . getData ( index ) , index ) ; if ( cmp == 0 ) { rval = node ; break ; } else { node = ( cmp < 0 ) ? node . getLeft ( index ) : node . getRight ( index ) ; } } return rval ; }

do the actual lookup of a piece of data

@param data the key or value to be looked up
@param index KEY or VALUE

@return the desired Node, or null if there is no mapping of the
specified data


private int compare(final int o1_status, final Object o1, final int o2_status, final Object o2, final int index) {
        if (comparators[index]==null) {
            if (o1 instanceof TransactionalComparable)
                return ((TransactionalComparable)o1).compareTo(o1_status, o2, o2_status);
            else
                return ((Comparable)o1).compareTo(o2);
        } else {
            return comparators[index].compare(o1, o2);
        }
    }

private int compare ( final int o1_status , final Object o1 , final int o2_status , final Object o2 , final int index ) { if ( comparators [ index ] == null ) { if ( o1 instanceof TransactionalComparable ) return ( ( TransactionalComparable ) o1 ) . compareTo ( o1_status , o2 , o2_status ) ; else return ( ( Comparable ) o1 ) . compareTo ( o2 ) ; } else { return comparators [ index ] . compare ( o1 , o2 ) ; } }

Compare two objects

@param o1 the first object
@param o2 the second object

@return negative value if o1 < o2; 0 if o1 == o2; positive
value if o1 > o2


private Node<K,V> leastNode(final Node<K,V> node, final int index) {

        Node<K,V> lval = node;

        if (lval != null) {
            while (lval.getLeft(index) != null) {
                lval = lval.getLeft(index);
            }
        }

        return lval;
    }

private Node < K , V > leastNode ( final Node < K , V > node , final int index ) { Node < K , V > lval = node ; if ( lval != null ) { while ( lval . getLeft ( index ) != null ) { lval = lval . getLeft ( index ) ; } } return lval ; }

find the least node from a given node. very useful for starting
a sorting iterator ...

@param node the node from which we will start searching
@param index KEY or VALUE

@return the smallest node, from the specified node, in the
specified mapping

find the least node from a given node . very useful for starting a sorting iterator ...


private Node<K,V> mostNode(final Node<K,V> node, final int index) {

        Node<K,V> rval = node;

        if (rval != null) {
            while (rval.getRight(index) != null) {
                rval = rval.getRight(index);
            }
        }

        return rval;
    }

private Node < K , V > mostNode ( final Node < K , V > node , final int index ) { Node < K , V > rval = node ; if ( rval != null ) { while ( rval . getRight ( index ) != null ) { rval = rval . getRight ( index ) ; } } return rval ; }

find the most node from a given node.

@param node the node from which we will start searching
@param index KEY or VALUE

@return the largest node, from the specified node, in the
specified mapping


private Node<K,V> nextGreater(final Node<K,V> node, final int index) {

        Node<K,V> rval;

        if (node == null) {
            rval = null;
        } else if (node.getRight(index) != null) {

            // everything to the node's right is larger. The least of
            // the right node's descendants is the next larger node
            rval = leastNode(node.getRight(index), index);
        } else {

            // traverse up our ancestry until we find an ancestor that
            // is null or one whose left child is our ancestor. If we
            // find a null, then this node IS the largest node in the
            // tree, and there is no greater node. Otherwise, we are
            // the largest node in the subtree on that ancestor's left
            // ... and that ancestor is the next greatest node
            Node<K,V> parent = node.getParent(index);
            Node<K,V> child  = node;

            while ((parent != null) && (child == parent.getRight(index))) {
                child  = parent;
                parent = parent.getParent(index);
            }

            rval = parent;
        }

        return rval;
    }

get the next larger node from the specified node

@param node the node to be searched from
@param index KEY or VALUE

@return the specified node


private Node<K,V> mostValidNode(final Node<K,V> node, final int index, final String thread_id) {
        Node<K,V> rval = node;

        while (rval != null && !validNode(rval, thread_id)) {
            rval = nextGreater(rval, index);
        }
        return rval;
    }

private Node < K , V > mostValidNode ( final Node < K , V > node , final int index , final String thread_id ) { Node < K , V > rval = node ; while ( rval != null && ! validNode ( rval , thread_id ) ) { rval = nextGreater ( rval , index ) ; } return rval ; }

get the most valid node from the specified node

@param node the node to be searched from
@param index KEY or VALUE

@return the specified node


private Node<K,V> leastValidNode(final Node<K,V> node, final int index, final String thread_id) {
        Node<K,V> lval = node;

        while (lval != null && !validNode(lval, thread_id)) {
            lval = nextSmaller(lval, index);
        }
        return lval;
    }

private Node < K , V > leastValidNode ( final Node < K , V > node , final int index , final String thread_id ) { Node < K , V > lval = node ; while ( lval != null && ! validNode ( lval , thread_id ) ) { lval = nextSmaller ( lval , index ) ; } return lval ; }

find the least valid node from a given node. very useful for starting
a sorting iterator ...

@param node the node from which we will start searching
@param index KEY or VALUE

@return the smallest valid node, from the specified node, in the
specified mapping

find the least valid node from a given node . very useful for starting a sorting iterator ...


private static <K,V> void copyColor(final Node<K,V> from, final Node<K,V> to,
                                  final int index) {

        if (to != null) {
            if (from == null) {

                // by default, make it black
                to.setBlack(index);
            } else {
                to.copyColor(from, index);
            }
        }
    }

private
static
<
K
,
V
>
void
copyColor
(
final
Node
<
K
,
V
>
from
,
final
Node
<
K
,
V
>
to
,
final
int
index
)
{
if
(
to
!=
)
{
if
(
from
==
)
{
// by default, make it black
to
.
setBlack
(
index
)
;
}
else
{
to
.
copyColor
(
from
,
index
)
;
}
}
}

copy the color from one node to another, dealing with the fact
that one or both nodes may, in fact, be null

@param from the node whose color we're copying; may be null
@param to the node whose color we're changing; may be null
@param index KEY or VALUE

copy the color from one node to another dealing with the fact that one or both nodes may in fact be null


private static <K,V> boolean isRed(final Node<K,V> node, final int index) {

        return ((node == null)
                ? false
                : node.isRed(index));
    }

private static < K , V > boolean isRed ( final Node < K , V > node , final int index ) { return ( ( node == null ) ? false : node . isRed ( index ) ) ; }

is the specified node red? if the node does not exist, no, it's
black, thank you

@param node the node (may be null) in question
@param index KEY or VALUE

is the specified node red? if the node does not exist no it s black thank you


private static <K,V> boolean isBlack(final Node<K,V> node, final int index) {

        return ((node == null)
                ? true
                : node.isBlack(index));
    }

private static < K , V > boolean isBlack ( final Node < K , V > node , final int index ) { return ( ( node == null ) ? true : node . isBlack ( index ) ) ; }

is the specified black red? if the node does not exist, sure,
it's black, thank you

@param node the node (may be null) in question
@param index KEY or VALUE

is the specified black red? if the node does not exist sure it s black thank you


private static <K,V> Node<K,V> getGrandParent(final Node<K,V> node, final int index) {
        return getParent(getParent(node, index), index);
    }

private static < K , V > Node < K , V > getGrandParent ( final Node < K , V > node , final int index ) { return getParent ( getParent ( node , index ) , index ) ; }

get a node's grandparent. mind you, the node, its parent, or
its grandparent may not exist. no problem

@param node the node (may be null) in question
@param index KEY or VALUE

get a node s grandparent . mind you the node its parent or its grandparent may not exist . no problem


private static <K,V> Node<K,V> getParent(final Node<K,V> node, final int index) {

        return ((node == null)
                ? null
                : node.getParent(index));
    }

private static < K , V > Node < K , V > getParent ( final Node < K , V > node , final int index ) { return ( ( node == null ) ? null : node . getParent ( index ) ) ; }

get a node's parent. mind you, the node, or its parent, may not
exist. no problem

@param node the node (may be null) in question
@param index KEY or VALUE

get a node s parent . mind you the node or its parent may not exist . no problem


private static <K,V> Node<K,V> getRightChild(final Node<K,V> node, final int index) {

        return (node == null)
               ? null
               : node.getRight(index);
    }

private static < K , V > Node < K , V > getRightChild ( final Node < K , V > node , final int index ) { return ( node == null ) ? null : node . getRight ( index ) ; }

get a node's right child. mind you, the node may not exist. no
problem

@param node the node (may be null) in question
@param index KEY or VALUE

get a node s right child . mind you the node may not exist . no problem


private static <K,V> Node<K,V> getLeftChild(final Node<K,V> node, final int index) {

        return (node == null)
               ? null
               : node.getLeft(index);
    }

private static < K , V > Node < K , V > getLeftChild ( final Node < K , V > node , final int index ) { return ( node == null ) ? null : node . getLeft ( index ) ; }

get a node's left child. mind you, the node may not exist. no
problem

@param node the node (may be null) in question
@param index KEY or VALUE

get a node s left child . mind you the node may not exist . no problem


private void rotateLeft(final Node<K,V> node, final int index) {

        Node<K,V> rightChild = node.getRight(index);

        node.setRight(rightChild.getLeft(index), index);

        if (rightChild.getLeft(index) != null) {
            rightChild.getLeft(index).setParent(node, index);
        }

        rightChild.setParent(node.getParent(index), index);

        if (node.getParent(index) == null) {

            // node was the root ... now its right child is the root
            rootNode[index] = rightChild;
        } else if (node.getParent(index).getLeft(index) == node) {
            node.getParent(index).setLeft(rightChild, index);
        } else {
            node.getParent(index).setRight(rightChild, index);
        }

        rightChild.setLeft(node, index);
        node.setParent(rightChild, index);
    }

do a rotate left. standard fare in the world of balanced trees

@param node the node to be rotated
@param index KEY or VALUE

do a rotate left . standard fare in the world of balanced trees


private void rotateRight(final Node<K,V> node, final int index) {

        Node<K,V> leftChild = node.getLeft(index);

        node.setLeft(leftChild.getRight(index), index);

        if (leftChild.getRight(index) != null) {
            leftChild.getRight(index).setParent(node, index);
        }

        leftChild.setParent(node.getParent(index), index);

        if (node.getParent(index) == null) {

            // node was the root ... now its left child is the root
            rootNode[index] = leftChild;
        } else if (node.getParent(index).getRight(index) == node) {
            node.getParent(index).setRight(leftChild, index);
        } else {
            node.getParent(index).setLeft(leftChild, index);
        }

        leftChild.setRight(node, index);
        node.setParent(leftChild, index);
    }

do a rotate right. standard fare in the world of balanced trees

@param node the node to be rotated
@param index KEY or VALUE

do a rotate right . standard fare in the world of balanced trees


private void doRedBlackInsert(final Node<K,V> insertedNode, final int index) {

        Node<K,V> currentNode = insertedNode;

        makeRed(currentNode, index);

        while ((currentNode != null) && (currentNode != rootNode[index])
                && (isRed(currentNode.getParent(index), index))) {
            if (isLeftChild(getParent(currentNode, index), index)) {
                Node<K,V> y = getRightChild(getGrandParent(currentNode, index),
                                       index);

                if (isRed(y, index)) {
                    makeBlack(getParent(currentNode, index), index);
                    makeBlack(y, index);
                    makeRed(getGrandParent(currentNode, index), index);

                    currentNode = getGrandParent(currentNode, index);
                } else {
                    if (isRightChild(currentNode, index)) {
                        currentNode = getParent(currentNode, index);

                        rotateLeft(currentNode, index);
                    }

                    makeBlack(getParent(currentNode, index), index);
                    makeRed(getGrandParent(currentNode, index), index);

                    if (getGrandParent(currentNode, index) != null) {
                        rotateRight(getGrandParent(currentNode, index),
                                    index);
                    }
                }
            } else {

                // just like clause above, except swap left for right
                Node<K,V> y = getLeftChild(getGrandParent(currentNode, index),
                                      index);

                if (isRed(y, index)) {
                    makeBlack(getParent(currentNode, index), index);
                    makeBlack(y, index);
                    makeRed(getGrandParent(currentNode, index), index);

                    currentNode = getGrandParent(currentNode, index);
                } else {
                    if (isLeftChild(currentNode, index)) {
                        currentNode = getParent(currentNode, index);

                        rotateRight(currentNode, index);
                    }

                    makeBlack(getParent(currentNode, index), index);
                    makeRed(getGrandParent(currentNode, index), index);

                    if (getGrandParent(currentNode, index) != null) {
                        rotateLeft(getGrandParent(currentNode, index), index);
                    }
                }
            }
        }

        makeBlack(rootNode[index], index);
    }

complicated red-black insert stuff. Based on Sun's TreeMap
implementation, though it's barely recognizable any more

@param insertedNode the node to be inserted
@param index KEY or VALUE

complicated red - black insert stuff . Based on Sun s TreeMap implementation though it s barely recognizable any more


private void doRedBlackDelete(final Node<K,V> deletedNode) {

        for (int index = FIRST_INDEX; index < NUMBER_OF_INDICES; index++) {

            // if deleted node has both left and children, swap with
            // the next greater node
            if ((deletedNode.getLeft(index) != null)
                    && (deletedNode.getRight(index) != null)) {
                swapPosition(nextGreater(deletedNode, index), deletedNode,
                             index);
            }

            Node<K,V> replacement = ((deletedNode.getLeft(index) != null)
                                ? deletedNode.getLeft(index)
                                : deletedNode.getRight(index));

            if (replacement != null) {
                replacement.setParent(deletedNode.getParent(index), index);

                if (deletedNode.getParent(index) == null) {
                    rootNode[index] = replacement;
                } else if (deletedNode
                           == deletedNode.getParent(index).getLeft(index)) {
                    deletedNode.getParent(index).setLeft(replacement, index);
                } else {
                    deletedNode.getParent(index).setRight(replacement, index);
                }

                deletedNode.setLeft(null, index);
                deletedNode.setRight(null, index);
                deletedNode.setParent(null, index);

                if (isBlack(deletedNode, index)) {
                    doRedBlackDeleteFixup(replacement, index);
                }
            } else {

                // replacement is null
                if (deletedNode.getParent(index) == null) {

                    // empty tree
                    rootNode[index] = null;
                } else {

                    // deleted node had no children
                    if (isBlack(deletedNode, index)) {
                        doRedBlackDeleteFixup(deletedNode, index);
                    }

                    if (deletedNode.getParent(index) != null) {
                        if (deletedNode
                                == deletedNode.getParent(index)
                                    .getLeft(index)) {
                            deletedNode.getParent(index).setLeft(null, index);
                        } else {
                            deletedNode.getParent(index).setRight(null,
                                                  index);
                        }

                        deletedNode.setParent(null, index);
                    }
                }
            }
        }

        shrink();
    }

complicated red-black delete stuff. Based on Sun's TreeMap
implementation, though it's barely recognizable any more

@param deletedNode the node to be deleted

complicated red - black delete stuff . Based on Sun s TreeMap implementation though it s barely recognizable any more


private void checkNonNullComparable(final Object o,
                                               final int index) {

        if (o == null) {
            throw new NullPointerException(dataName[index]
                                           + " cannot be null");
        }

        if (comparators[index] == null && !(o instanceof Comparable)) {
            throw new ClassCastException(dataName[index]
                                         + " must be Comparable");
        }
    }

private
void
checkNonNullComparable
(
final
Object
o
,
final
int
index
)
{
if
(
o
==
)
{
throw
new
NullPointerException
(
dataName
[
index
]
+
" cannot be null"
)
;
}
if
(
comparators
[
index
]
==
&&
!
(
o
instanceof
Comparable
)
)
{
throw
new
ClassCastException
(
dataName
[
index
]
+
" must be Comparable"
)
;
}
}

check if an object is fit to be proper input ... has to be
Comparable if the comparator has not been set and non-null

@param o the object being checked
@param index KEY or VALUE (used to put the right word in the
exception message)

@throws NullPointerException if o is null
@throws ClassCastException if o is not Comparable and the
equivalent comparator has not been set

check if an object is fit to be proper input ... has to be Comparable if the comparator has not been set and non - null