Example usage for java.util HashSet isEmpty

List of usage examples for java.util HashSet isEmpty

Introduction

In this page you can find the example usage for java.util HashSet isEmpty.

Prototype

public boolean isEmpty() 

Source Link

Document

Returns true if this set contains no elements.

Usage

From source file:com.zimbra.cs.account.ldap.LdapProvisioning.java

private void removeDistributionListMembers(DistributionList dl, String[] members) throws ServiceException {
    Set<String> curMembers = dl.getMultiAttrSet(Provisioning.A_zimbraMailForwardingAddress);

    // bug 46219, need a case insentitive Set
    Set<String> existing = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
    existing.addAll(curMembers);// w  w  w.ja v  a  2 s .c o m

    Set<String> mods = new HashSet<String>();
    HashSet<String> failed = new HashSet<String>();

    for (int i = 0; i < members.length; i++) {
        String memberName = members[i].toLowerCase();
        memberName = IDNUtil.toAsciiEmail(memberName);
        if (memberName.length() == 0) {
            throw ServiceException.INVALID_REQUEST("invalid member email address: " + memberName, null);
        }
        // We do not do any further validation of the remove address for
        // syntax - removes should be liberal so any bad entries added by
        // some other means can be removed
        //
        // members[] can contain:
        //   - the primary address of an account or another DL
        //   - an alias of an account or another DL
        //   - junk (allAddrs will be returned as null)
        AddrsOfEntry addrsOfEntry = getAllAddressesOfEntry(memberName);
        List<String> allAddrs = addrsOfEntry.getAll();

        if (mods.contains(memberName)) {
            // already been added in mods (is the primary or alias of previous entries in members[])
        } else if (existing.contains(memberName)) {
            if (!allAddrs.isEmpty()) {
                mods.addAll(allAddrs);
            } else {
                mods.add(memberName); // just get rid of it regardless what it is
            }
        } else {
            boolean inList = false;
            if (allAddrs.size() > 0) {
                // go through all addresses of the entry see if any is on the DL
                for (String addr : allAddrs) {
                    if (!inList) {
                        break;
                    }
                    if (existing.contains(addr)) {
                        mods.addAll(allAddrs);
                        inList = true;
                    }
                }
            }
            if (!inList) {
                failed.add(memberName);
            }
        }

        // clear the DL cache on accounts/dl
        String primary = addrsOfEntry.getPrimary();
        if (primary != null) {
            if (addrsOfEntry.isAccount()) {
                Account acct = getFromCache(AccountBy.name, primary);
                if (acct != null)
                    clearUpwardMembershipCache(acct);
            } else {
                removeGroupFromCache(Key.DistributionListBy.name, primary);
            }
        }
    }

    if (!failed.isEmpty()) {
        StringBuilder sb = new StringBuilder();
        Iterator<String> iter = failed.iterator();
        while (true) {
            sb.append(iter.next());
            if (!iter.hasNext())
                break;
            sb.append(",");
        }
        throw AccountServiceException.NO_SUCH_MEMBER(dl.getName(), sb.toString());
    }

    if (mods.isEmpty()) {
        throw ServiceException.INVALID_REQUEST("empty remove set", null);
    }

    PermissionCache.invalidateCache();
    cleanGroupMembersCache(dl);

    Map<String, String[]> modmap = new HashMap<String, String[]>();
    modmap.put("-" + Provisioning.A_zimbraMailForwardingAddress, mods.toArray(new String[0]));
    modifyAttrs(dl, modmap);

}

From source file:StreamFlusher.java

public Object visit(ASTnet_list_get_sigma_func_call node, Object data) {
    // $@^__getSigma($fst)
    // one daughter
    //      regexp
    // return the sigma as an array of nets, one for each symbol in
    // the sigma (minus special chars starting "__" that should not be 
    // considered when promoting OTHER)

    node.jjtGetChild(0).jjtAccept(this, data);
    Fst fst = (Fst) (stack.pop());//from w w w.j av a  2  s  .  c o m

    NetList resultList = new NetList();

    String specialSymbolPrefix = "__";
    HashSet<Integer> sigma = fst.getSigma();
    String symbolName = "";

    if (!sigma.isEmpty()) {
        for (Iterator<Integer> iter = sigma.iterator(); iter.hasNext();) {
            int cpv = iter.next().intValue();
            symbolName = symmap.getsym(cpv);
            if (!(symbolName.startsWith(specialSymbolPrefix))) {
                resultList.add(lib.OneArcFst(cpv));
            }
        }
    }

    stack.push(resultList);
    return data;
}

From source file:StreamFlusher.java

public Object visit(ASTnum_list_get_sigma_func_call node, Object data) {
    // #@^__getSigma($fst)
    // one daughter
    //      regexp
    // return the sigma as an array of Integer, one for each symbol in
    // the sigma (minus special chars starting "__" that should not be
    // considered when promoting OTHER)

    node.jjtGetChild(0).jjtAccept(this, data);
    Fst fst = (Fst) (stack.pop());//from w ww.j  av a  2 s  .c  o m

    NumList resultList = new NumList();

    String specialSymbolPrefix = "__";
    HashSet<Integer> sigma = fst.getSigma();
    String symbolName = "";

    if (!sigma.isEmpty()) {
        for (Iterator<Integer> iter = sigma.iterator(); iter.hasNext();) {
            int cpv = iter.next().intValue();
            symbolName = symmap.getsym(cpv);
            if (!(symbolName.startsWith(specialSymbolPrefix))) {
                resultList.add(new Long(cpv));
            }
        }
    }

    stack.push(resultList);
    return data;
}

From source file:StreamFlusher.java

private void findDependencies(Fst fst, ArrayList<String> dependencies) {
    String subnetReferencePrefix = "";
    if (isOpenFstRtnConventions()) {
        subnetReferencePrefix = "__$";
    } else {//from w ww. ja v a  2s  . c  o m
        subnetReferencePrefix = "$";
    }
    HashSet<Integer> sigma = fst.getSigma();
    String symbolName = "";
    String netIdName = "";

    if (!sigma.isEmpty()) {
        for (Iterator<Integer> iter = sigma.iterator(); iter.hasNext();) {
            // the name should look like "a", "b", and perhaps
            // "__$sub" (for OpenFstRtnConventions) or "$sub" (for SapRtnConventions)
            symbolName = symmap.getsym(iter.next().intValue());
            if (symbolName.startsWith(subnetReferencePrefix)) {
                // save the subnet name, minus any prefix
                netIdName = symbolName.substring(symbolName.indexOf("$"));
                // avoid duplicates
                if (!dependencies.contains(netIdName)) {
                    dependencies.add(netIdName);
                }
            }
        }
    }
}

From source file:StreamFlusher.java

public Object visit(ASTnet_start_func_call node, Object data) {
    // syntax:   $^start($>foo)   a built-in function-like regexp
    // Not really implemented as a function, cannot be aliased, i.e.
    // $^debut = $^start  is not legal
    // The value of the statement, if successful, is an Fst.

    // just one daughter: ASTrrprod_id, which includes the name
    // of the start production 
    // (This is constrained syntactically by the parser)
    // Don't evaluate daughter.  Just retrieve the image.
    String rrprod_id = ((ASTrrprod_id) node.jjtGetChild(0)).getImage();

    // The rrprod_id argument to $^start() will be the root of the 
    //      right-linear grammar,
    // but rrprod_id may refer to other productions, which may, 
    //      in turn, refer
    // to other productions, etc.  (even circular references).
    // Need to check that all the RrDependencies ("right-recursive") 
    //      of $>foo are defined,
    // and that all the dependencies of the dependencies are defined,
    // etc./* w  ww.  j ava 2 s. c  o m*/

    // Check and list dependencies (the productions)
    // for the whole implied grammar, keep them in an ArrayList
    // (I tried to use a HashSet, but this proved to be
    // impossible to iterate through AND increase in size)
    ArrayList<String> dependencies = new ArrayList<String>();
    dependencies.add(rrprod_id);
    // Start with the current rrprod_id (the start); use ArrayList
    // so that dependencies of the overall grammar are added only
    // once (no duplicates).  The order of objects in the ArrayList
    // is constant and starts at index 0

    // Now loop through the ArrayList of dependencies, adding new ones 
    // as they appear
    // (use a for-loop so that the size can grow during iteration--
    // tried to use HashSet, but this proved impossible)
    for (int i = 0; i < dependencies.size(); i++) {
        String dep = dependencies.get(i);
        // Look up the dependency name (getting back an RrProdObject)
        // if successful (i.e. is in the symbol table).
        RrProdObject rrProdObject = (RrProdObject) env.get(dep);
        if (rrProdObject == null) {
            throw new UndefinedIdException("Undefined rrprod_id: " + dep);
        }
        // also check net_id and other _id references? or catch during
        // interpretation?  
        // The dependencies of each defined production are stored 
        // in the symbol table as part of the RrProdObject, 
        // as a HashSet
        HashSet<String> hs = rrProdObject.getRrDependencies();
        if (!hs.isEmpty()) {
            for (Iterator<String> iter = hs.iterator(); iter.hasNext();) {
                String s = iter.next();
                // if the overall list of dependencies does not yet
                // contain s, then add it
                if (!dependencies.contains(s)) {
                    dependencies.add(s);
                }
            }
        }
    }

    // Reaching here, the whole Rr grammar has been defined.
    // (All the required Rr productions are available in the
    // symbol table.)

    // Create an Fst result.
    // Need to copy all the states and arcs of networks 
    //      of the productions
    // into the result network, keeping track of the 
    //      new startStateNum of each network.  
    // (This is a modification of the concatenation
    // algorithm of OpenFst, minus the code that creates an 
    //      epsilon arc from the final state(s) of the first 
    //      network to the start state of the second.
    //
    // Try to compile each network in the grammar.  Initially
    // each right-recursive reference $>foo is treated much 
    // like a multichar-symbol, but with
    // a negative code point value (a negative label value on an arc).
    // These negative code point values should not be added to
    // the sigma.

    Fst resultFst = null;

    // Instead of a HashMap, use two parallel ArrayLists,
    // later converted to int[], to pass easily to a C++ 
    // native function that stitches the network together.

    // ArrayLists expand as necessary; avoid any preconceived
    // size limit.
    ArrayList<Integer> keys = new ArrayList<Integer>();
    ArrayList<Integer> vals = new ArrayList<Integer>();
    //  will have neg ints (representing $>foo refs) mapped 
    // to positive numbers corresponding to start states of the
    // various dependencies (productions) in the overall grammar.

    // Again loop through the list of dependencies (the names
    // of all the productions in the implied grammar);
    // they are "defined" (stored as ASTs) but not yet
    // "evaluated" into FSTs

    for (int i = 0; i < dependencies.size(); i++) {
        String rrprod = dependencies.get(i);

        RrProdObject rrProdObject = (RrProdObject) env.get(rrprod);
        // get the AST (.getRHS()), 
        // and evaluate it to produce an Fst object
        ASTrrProdRHS astRrProdRHS = rrProdObject.getRHS();
        astRrProdRHS.jjtAccept(this, data);
        // should leave an Fst object on the stack, for one production
        Fst fst = (Fst) stack.pop();

        int startStateNum;

        if (i == 0) {
            // the zeroth is the root production
            resultFst = lib.CopyFst(fst);
            startStateNum = lib.StartState(resultFst);
        } else {
            // returns the _new_ start state number of fst
            startStateNum = lib.AddStatesAndArcsInPlace(resultFst, fst);

        }

        // A rrprod_id like $>foo is stored with a NEGATIVE int value
        // on an Fst arc.
        int negcpv = symmap.getint(rrprod);

        // effectively create a Map from neg. int keys 
        //   (right-linear labels)to non-neg.
        // integers that represent the new state number of the start
        // state of this particular Fst (for one of the productions
        // of the overall grammar); 
        keys.add(negcpv); // will be a negative int value
        vals.add(startStateNum);
    }

    // Now need to "stitch" it all together

    lib.RrGrammarLinkInPlace(resultFst, keys, vals);

    stack.push(resultFst);
    return data;
}

From source file:StreamFlusher.java

public Object visit(ASTnet_embed_rtn_subnets_func_call node, Object data) {

    // evaluate the argument, a regexp, leaving an Fst object on the stack
    node.jjtGetChild(0).jjtAccept(this, data);
    Fst baseFst = (Fst) (stack.pop());// w  ww. j a  va  2s.c  om

    // Check and list dependencies (the subnetworks)
    // for the whole implied RTN, keep them in an ArrayList
    // (HashSet would be convenient, but you can't iterate through it
    // and add objects to it during the iteration).  HashSet would keep
    // out duplicates automatically--it's a bit harder with ArrayList.

    ArrayList<String> dependencies = new ArrayList<String>();

    // find all subnets referred to by the baseFst
    findDependencies(baseFst, dependencies);

    // The order of objects in the ArrayList is constant and starts at index 0

    // Now loop through the ArrayList of dependencies, which is a set (no
    // duplicates) adding new dependencies as they appear
    // (use a for-loop so that the size can grow during iteration--
    // I tried to use HashSet, but this proved impossible)

    String dep;

    // keep a set of dependencies that are not defined (any
    // undefined dependency is an error)
    HashSet<String> not_defined = new HashSet<String>();

    for (int i = 0; i < dependencies.size(); i++) {
        dep = dependencies.get(i);

        // Look up the dependency name in the symbol table.
        Fst fst = (Fst) env.get(dep);
        if (fst == null) {
            // add it to the set of undefined dependencies
            not_defined.add(dep);
            continue;
        }
        // find any additional dependencies of this dependency
        findDependencies(fst, dependencies);
    }

    // if any dependencies are not defined, throw an exception
    if (!not_defined.isEmpty()) {
        throw new UndefinedIdException("Undefined networks: " + not_defined.toString());
    }

    // Reaching here, the whole RTN grammar has been defined.
    // (All the required networks are available in the
    // symbol table.)

    // Create an Fst result that incorporates the subnetworks,
    // unioning them in (with special prefixes) with the base
    // network.

    // EmbeddedRtn is not destructive; copies baseFst
    // if it comes from a symbol table
    Fst resultFst = lib.EmbeddedRtn(baseFst, dependencies, "__SUBNETWORKS");
    stack.push(resultFst);
    return data;
}

From source file:StreamFlusher.java

public Object visit(ASTnet_expand_rtn_func_call node, Object data) {

    // syntax  $^expandRtn(regexp)

    if (lib.isSapRtnConventions()) {
        throw new KleeneInterpreterException("$^expandRtn() is not yet implemented under SapRtnConventions");
    }/*from  w w w  . j  a v  a 2s.  com*/

    // evaluate the one argument, a regexp, 
    // leaving an Fst object on the stack
    node.jjtGetChild(0).jjtAccept(this, data);
    Fst baseFst = (Fst) (stack.pop());

    int baseFstInt;
    if (baseFst.getFromSymtab()) {
        // then reach down into the AST to get the image
        String net_id = ((ASTnet_id) (node.jjtGetChild(0).jjtGetChild(0))).getImage();
        baseFstInt = symmap.putsym("__" + net_id);
    } else {
        baseFstInt = -1000000; // KRB: magic number
    }

    // a HashSet would be more convenient, but you can't iterate through
    // it and add to it
    ArrayList<String> subnetReferences = new ArrayList<String>();

    // find subnet references in the baseFst
    findSubnetReferences(baseFst, subnetReferences);

    // The order of objects in the ArrayList is constant and starts at index 0

    // Now loop through the ArrayList of subnetReferences, adding new ones 
    // as they appear
    // (use a for-loop so that the size can grow during iteration--
    // I tried to use HashSet and an Iterator, but this proved impossible)

    // Collect a set of undefined networks (if any)
    HashSet<String> not_defined = new HashSet<String>();

    String subnetName;
    Fst subFst;

    for (int i = 0; i < subnetReferences.size(); i++) {
        subnetName = subnetReferences.get(i);

        // Look up the subnet name in the symbol table.
        subFst = (Fst) env.get(subnetName);
        if (subFst == null) {
            // add it to the list
            not_defined.add(subnetName);
            continue;
        }
        // also look for subnet references in this subnet
        findSubnetReferences(subFst, subnetReferences);
    }

    // bail out here, with a useful Exception message, if any
    // of the required subnets are not defined.
    if (!not_defined.isEmpty()) {
        throw new UndefinedIdException("Failed RTN expansion, undefined networks: " + not_defined.toString());
    }

    // Reaching here, the whole RTN grammar has been defined.
    // (All the required networks are available in the
    // symbol table.)

    Fst resultFst = lib.ExpandRtn(baseFst, baseFstInt, subnetReferences);

    stack.push(resultFst);
    return data;
}

From source file:com.crushpaper.DbLogic.java

/** Helper method. Does all the real work for restoreJsonForUser(). */
public boolean reallyRestoreJsonForUser(String userId, InputStreamReader streamReader, boolean reuseIds,
        boolean isAdmin, Errors errors) {

    if (userId == null) {
        Errors.add(errors, errorMessages.errorsUserIdIsNull());
        return false;
    }/*from w ww  .j  a v a  2 s .c o m*/

    if (streamReader == null) {
        Errors.add(errors, errorMessages.errorsTheInputStreamReaderIsNull());
        return false;
    }

    try {
        ObjectMapper mapper = new ObjectMapper();
        JsonNodeHelper json = new JsonNodeHelper(mapper.readTree(streamReader));

        // Save the restored IDs for later.
        final HashMap<String, String> restoredEntryIdToRealEntryId = new HashMap<String, String>();
        final HashMap<String, String> realEntryIdToRestoredEntryId = new HashMap<String, String>();
        final HashMap<String, String> entryIdToParentRestoredEntryId = new HashMap<String, String>();
        final HashMap<String, String> entryIdToSourceRestoredEntryId = new HashMap<String, String>();
        final HashMap<String, String> entryIdToRootRestoredEntryId = new HashMap<String, String>();
        final HashMap<String, ChildrenInfo> restoredEntryIdToChildren = new HashMap<String, ChildrenInfo>();
        final HashSet<String> rootRestoredEntryIds = new HashSet<String>();

        JsonNodeHelper[] entries = json.getJsonArray("entries");
        if (entries != null) {
            for (JsonNodeHelper jsonEntry : entries) {
                final User user = getUserById(userId);
                if (user == null) {
                    return false;
                }

                final String sourceId = jsonEntry.getString("sourceId");
                final String type = jsonEntry.getString(DbLogic.Constants.type);
                final String id = jsonEntry.getString(DbLogic.Constants.id);
                final String quotation = jsonEntry.getString(DbLogic.Constants.quotation);
                final String note = jsonEntry.getString(DbLogic.Constants.note);

                Long createTime = jsonEntry.getLong(DbLogic.Constants.createTime);
                if (createTime == null) {
                    createTime = new Long(System.currentTimeMillis());
                }

                Long modTime = jsonEntry.getLong(DbLogic.Constants.modTime);
                if (modTime == null) {
                    modTime = createTime;
                }

                final String nextSiblingId = jsonEntry.getString(DbLogic.Constants.nextSiblingId);
                final String parentId = jsonEntry.getString(DbLogic.Constants.parentId);
                final boolean isPublic = jsonEntry.getBoolean(DbLogic.Constants.isPublic);
                final String url = jsonEntry.getString(DbLogic.Constants.url);
                final String rootId = jsonEntry.getString(DbLogic.Constants.rootId);

                if (type == null) {
                    Errors.add(errors, errorMessages.errorTheTypeOfTheEntryIsNotAllowed(id));
                    return false;
                }

                if (type.equals(Constants.note) && !EntryAttributeValidator.isNoteValid(note)) {
                    Errors.add(errors, errorMessages.errorNoteIsInvalid(id));
                    return false;
                }

                if (type.equals(Constants.notebook) && !EntryAttributeValidator.isNotebookTitleValid(note)) {
                    Errors.add(errors, errorMessages.errorNoteIsInvalid(id));
                    return false;
                }

                if (!EntryAttributeValidator.isQuotationValid(quotation)) {
                    Errors.add(errors, errorMessages.errorQuotationIsInvalid(id));
                    return false;
                }

                if (!EntryAttributeValidator.isUrlValid(url)) {
                    Errors.add(errors, errorMessages.errorUrlIsInvalid(id));
                    return false;
                }

                if (type.equals(Constants.source) && !EntryAttributeValidator.isSourceTitleValid(note)) {
                    Errors.add(errors, errorMessages.errorTitleIsInvalid(id));
                    return false;
                }

                if (!type.equals(Constants.quotation) && sourceId != null) {
                    Errors.add(errors, errorMessages.errorOnlyQuotationsMayHaveASource(id));
                    return false;
                }

                if (!type.equals(Constants.quotation) && quotation != null) {
                    Errors.add(errors, errorMessages.errorOnlyQuotationsMayHaveAQuotation(id));
                    return false;
                }

                if (!type.equals(Constants.source) && url != null) {
                    Errors.add(errors, errorMessages.errorOnlySourcesMayHaveAUrl(id));
                    return false;
                }

                if (!type.equals(Constants.notebook) && rootId != null) {
                    Errors.add(errors, errorMessages.errorOnlyNotebooksMayHaveARoot(id));
                    return false;
                }

                if (type.equals(Constants.notebook) && rootId == null) {
                    Errors.add(errors, errorMessages.errorNotebooksMustHaveARootId(id));
                    return false;
                }

                if (type.equals(Constants.tableofcontents)) {
                    Errors.add(errors, errorMessages.errorTableOfContentsMayNotBeRestored(id));
                    return false;
                }

                if ((type.equals(Constants.root) || type.equals(Constants.tableofcontents))
                        && parentId != null) {
                    Errors.add(errors,
                            errorMessages.errorRootsAndTableOfContentsCanNotBeCreatedWithARelationship(id));
                    return false;
                }

                if (!(type.equals(Constants.root) || type.equals(Constants.notebook)
                        || type.equals(Constants.source) || type.equals(Constants.quotation))
                        && parentId == null) {
                    Errors.add(errors, errorMessages
                            .errorOnlyRootsNotebooksSourcesAndQuotationsCanBeCreatedWithOutAParent(id));
                    return false;
                }

                // Reuse IDs if possible.
                String newRealId = null;
                if (reuseIds && getEntryById(id) == null) {
                    newRealId = id;
                }

                Entry entry = null;
                if (type.equals(Constants.source)) {
                    // Create the entry.
                    entry = updateOrCreateSource(user, newRealId, url, note, modTime, createTime, isAdmin,
                            errors);
                    if (entry == null) {
                        return false;
                    }
                } else {
                    // Create the entry.
                    entry = createRawEntry(user, null, type, newRealId, quotation, note, modTime, createTime,
                            isPublic, isAdmin, errors);
                    if (entry == null) {
                        return false;
                    }

                    if (sourceId != null) {
                        entryIdToSourceRestoredEntryId.put(entry.getId(), sourceId);
                    }
                }

                if (type.equals(Constants.root)) {
                    rootRestoredEntryIds.add(id);
                }

                // Save the restored entry IDs for later.
                if (id != null) {
                    if (restoredEntryIdToRealEntryId.containsKey(id)) {
                        Errors.add(errors, errorMessages.errorDuplicateId(id));
                        return false;
                    }

                    restoredEntryIdToRealEntryId.put(id, entry.getId());
                    realEntryIdToRestoredEntryId.put(entry.getId(), id);
                }

                if (parentId != null) {
                    entryIdToParentRestoredEntryId.put(entry.getId(), parentId);

                    ChildrenInfo parentsChildren = restoredEntryIdToChildren.get(parentId);
                    if (parentsChildren == null) {
                        parentsChildren = new ChildrenInfo();
                        restoredEntryIdToChildren.put(parentId, parentsChildren);
                    }

                    parentsChildren.restoredNextToRealPreviousIds.put(nextSiblingId, entry.getId());
                    ++parentsChildren.count;

                    if (nextSiblingId == null)
                        parentsChildren.lastRealId = entry.getId();
                }

                if (rootId != null) {
                    entryIdToRootRestoredEntryId.put(entry.getId(), rootId);
                }
            }
        }

        // Now create the parent relationships.
        for (final Map.Entry<String, String> entry : entryIdToParentRestoredEntryId.entrySet()) {
            final User user = getUserById(userId);
            if (user == null) {
                return false;
            }

            final String childId = entry.getKey();
            final String restoredParentId = entry.getValue();
            final String parentId = restoredEntryIdToRealEntryId.get(restoredParentId);
            if (parentId == null) {
                Errors.add(errors, errorMessages.errorParentIdWasNotFound(restoredParentId));
                return false;
            }

            final Entry child = getEntryById(childId);
            final Entry parent = getEntryById(parentId);
            if (!verifyTypesForParentChildRelationship(child.getType(), parent.getType(),
                    realEntryIdToRestoredEntryId.get(childId), errors)) {
                return false;
            }

            if (!createParentChildRelationship(user, parent, child, null, isAdmin, errors)) {
                return false;
            }
        }

        // Now create the source relationships.
        for (final Map.Entry<String, String> mapEntry : entryIdToSourceRestoredEntryId.entrySet()) {
            final User user = getUserById(userId);
            if (user == null) {
                return false;
            }

            final String entryId = mapEntry.getKey();
            final String restoredSourceId = mapEntry.getValue();
            final String sourceId = restoredEntryIdToRealEntryId.get(restoredSourceId);
            if (sourceId == null) {
                Errors.add(errors, errorMessages.errorSourceIdWasNotFound(restoredSourceId));
                return false;
            }

            final Entry source = getEntryById(sourceId);
            if (!source.isSource()) {
                Errors.add(errors, errorMessages.errorSourceIdWasNotASource(restoredSourceId));
                return false;
            }

            final Entry entry = getEntryById(entryId);
            entry.setSourceId(sourceId);
        }

        // Now create the sibling relationships.
        for (final Map.Entry<String, ChildrenInfo> mapEntry : restoredEntryIdToChildren.entrySet()) {
            final ChildrenInfo childrenInfo = mapEntry.getValue();
            if (childrenInfo.count == childrenInfo.restoredNextToRealPreviousIds.size()) {
                LinkedList<String> sortedRealChildIds = getRealChildIdsInOrderForUserRestore(childrenInfo,
                        realEntryIdToRestoredEntryId, errors);
                if (sortedRealChildIds == null) {
                    return false;
                }

                for (String realChildId : sortedRealChildIds) {
                    final User user = getUserById(userId);
                    if (user == null) {
                        return false;
                    }

                    final Entry entry = getEntryById(realChildId);
                    if (!makeEntryLastChild(user, entry, errors)) {
                        return false;
                    }
                }
            }
        }

        // Now create the root relationships.
        for (final Map.Entry<String, String> mapEntry : entryIdToRootRestoredEntryId.entrySet()) {
            final User user = getUserById(userId);
            if (user == null) {
                return false;
            }

            final String notebookId = mapEntry.getKey();
            final String restoredRootId = mapEntry.getValue();
            final String rootId = restoredEntryIdToRealEntryId.get(restoredRootId);
            if (rootId == null) {
                Errors.add(errors, errorMessages.errorRootIdWasNotFound(restoredRootId));
                return false;
            }

            final Entry notebook = getEntryById(notebookId);
            final Entry root = getEntryById(rootId);
            if (!root.getType().equals(Constants.root)) {
                Errors.add(errors, errorMessages.errorRootIdWasNotARoot(restoredRootId));
                return false;
            }

            rootRestoredEntryIds.remove(restoredRootId);
            notebook.setRootId(rootId);
            root.setNotebookId(notebookId);
        }

        if (!rootRestoredEntryIds.isEmpty()) {
            Errors.add(errors, errorMessages.errorNotAllRootsHadNotebooks());
            return false;
        }
    } catch (final IOException e) {
        Errors.add(errors, errorMessages.errorJson());
        return false;
    }

    return true;
}

From source file:net.rptools.maptool.client.MapToolLineParser.java

public String parseLine(MapToolVariableResolver res, Token tokenInContext, String line,
        MapToolMacroContext context) throws ParserException {
    if (line == null) {
        return "";
    }/*w ww  .  j a  va  2s  .  c o  m*/
    line = line.trim();
    if (line.length() == 0) {
        return "";
    }
    Stack<Token> contextTokenStack = new Stack<Token>();
    enterContext(context);
    MapToolVariableResolver resolver = null;
    boolean resolverInitialized = false;
    String opts = null;
    String roll = null;
    try {
        // Keep the same variable context for this line
        resolver = (res == null) ? new MapToolVariableResolver(tokenInContext) : res;
        resolverInitialized = resolver.initialize();
        StringBuilder builder = new StringBuilder();
        int start = 0;
        List<InlineRollMatch> matches = this.locateInlineRolls(line);

        for (InlineRollMatch match : matches) {
            builder.append(line.substring(start, match.getStart())); // add everything before the roll

            start = match.getEnd() + 1;
            // These variables will hold data extracted from the roll options.
            Output output;
            if (MapTool.useToolTipsForUnformatedRolls()) {
                output = Output.TOOLTIP;
            } else {
                output = Output.EXPANDED;
            }
            String text = null; // used by the T option
            HashSet<String> outputOpts = new HashSet<String>();
            OutputLoc outputTo = OutputLoc.CHAT;

            LoopType loopType = LoopType.NO_LOOP;
            int loopStart = 0, loopEnd = 0, loopStep = 1;
            int loopCount = 0;
            String loopSep = null;
            String loopVar = null, loopCondition = null;
            List<String> foreachList = new ArrayList<String>();

            BranchType branchType = BranchType.NO_BRANCH;
            Object branchCondition = null;

            CodeType codeType = CodeType.NO_CODE;
            String macroName = null;

            String frameName = null;
            String frameOpts = null;

            if (match.getMatch().startsWith("[")) {
                opts = match.getOpt();
                roll = match.getRoll();
                if (opts != null) {
                    // Turn the opts string into a list of OptionInfo objects.
                    List<OptionInfo> optionList = null;
                    try {
                        optionList = getRollOptionList(opts);
                    } catch (RollOptionException roe) {
                        throw doError(roe.msg, opts, roll);
                    }

                    // Scan the roll options and prepare variables for later use
                    for (OptionInfo option : optionList) {
                        String error = null;
                        /*
                         * TODO: If you're adding a new option, add a new
                         * case here to collect info from the parameters. If
                         * your option uses parameters, use the
                         * option.getXxxParam() methods to get the text or
                         * parsed values of the parameters.
                         */
                        switch (option.optionType) {

                        ///////////////////////////////////////////////////
                        // OUTPUT FORMAT OPTIONS
                        ///////////////////////////////////////////////////
                        case HIDDEN:
                            output = Output.NONE;
                            break;
                        case RESULT:
                            output = Output.RESULT;
                            break;
                        case EXPANDED:
                            output = Output.EXPANDED;
                            break;
                        case UNFORMATTED:
                            output = Output.UNFORMATTED;
                            outputOpts.add("u");
                            break;
                        case TOOLTIP:
                            // T(display_text)
                            output = Output.TOOLTIP;
                            text = option.getStringParam(0);
                            break;

                        ///////////////////////////////////////////////////
                        // VISIBILITY OPTIONS
                        ///////////////////////////////////////////////////
                        case GM:
                            outputOpts.add("g");
                            break;
                        case SELF:
                            outputOpts.add("s");
                            break;
                        case WHISPER:
                            outputOpts.add("w");
                            for (int i = 0; i < option.getParamCount(); i++) {
                                String arg = parseExpression(resolver, tokenInContext, option.getStringParam(i))
                                        .getValue().toString();
                                if (arg.trim().startsWith("[")) {
                                    Object json = JSONMacroFunctions.convertToJSON(arg);
                                    if (json instanceof JSONArray) {
                                        for (Object name : (JSONArray) json) {
                                            outputOpts.add("w:" + name.toString().toLowerCase());
                                        }
                                    }
                                } else
                                    outputOpts.add("w:" + arg.toLowerCase());
                            }
                            break;

                        ///////////////////////////////////////////////////
                        // TOOLTIP VISIBILITY OPTIONS
                        ///////////////////////////////////////////////////
                        case GMTT:
                            outputOpts.add("gt");
                            break;
                        case SELFTT:
                            outputOpts.add("st");
                            break;

                        ///////////////////////////////////////////////////
                        // LOOP OPTIONS
                        ///////////////////////////////////////////////////
                        case COUNT:
                            // COUNT(num [, sep])
                            loopType = LoopType.COUNT;
                            error = null;
                            try {
                                loopCount = option.getParsedIntParam(0, resolver, tokenInContext);
                                if (loopCount < 0)
                                    error = I18N.getText("lineParser.countNonNeg", loopCount);
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "COUNT", pe.getMessage());
                            }
                            loopSep = option.getStringParam(1);

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case FOR:
                            // FOR(var, start, end [, step [, sep]])
                            loopType = LoopType.FOR;
                            error = null;
                            try {
                                loopVar = option.getIdentifierParam(0);
                                loopStart = option.getParsedIntParam(1, resolver, tokenInContext);
                                loopEnd = option.getParsedIntParam(2, resolver, tokenInContext);
                                try {
                                    loopStep = option.getParsedIntParam(3, resolver, tokenInContext);
                                } catch (ParserException pe) {
                                    // Build a more informative error message for this common mistake
                                    String msg = pe.getMessage();
                                    msg = msg + " " + I18N.getText("lineParser.nonDefLoopSep");
                                    throw new ParserException(msg);
                                }
                                loopSep = option.getStringParam(4);
                                if (loopStep != 0)
                                    loopCount = Math.max(1, (int) Math.ceil(
                                            Math.abs((double) (loopEnd - loopStart) / (double) loopStep)));

                                if (loopVar.equalsIgnoreCase(""))
                                    error = I18N.getText("lineParser.forVarMissing");
                                if (loopStep == 0)
                                    error = I18N.getText("lineParser.forNoZeroStep");
                                if ((loopEnd <= loopStart && loopStep > 0)
                                        || (loopEnd >= loopStart && loopStep < 0))
                                    loopCount = 0;
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "FOR", pe.getMessage());
                            }

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case FOREACH:
                            // FOREACH(var, list [, outputDelim [, inputDelim]])
                            loopType = LoopType.FOREACH;
                            error = null;
                            try {
                                loopVar = option.getIdentifierParam(0);
                                String listString = option.getParsedParam(1, resolver, tokenInContext)
                                        .toString();
                                loopSep = option.getStringParam(2);
                                String listDelim = option.getStringParam(3);
                                if (listDelim.trim().startsWith("\"")) {
                                    listDelim = parseExpression(resolver, tokenInContext, listDelim).getValue()
                                            .toString();
                                }

                                foreachList = null;
                                if (listString.trim().startsWith("{") || listString.trim().startsWith("[")) {
                                    // if String starts with [ or { it is JSON -- try to treat it as a JSON String
                                    Object obj = JSONMacroFunctions.convertToJSON(listString);
                                    if (obj != null) {
                                        foreachList = new ArrayList<String>();
                                        if (obj instanceof JSONArray) {
                                            for (Object o : ((JSONArray) obj).toArray()) {
                                                foreachList.add(o.toString());
                                            }
                                        } else {
                                            @SuppressWarnings("unchecked")
                                            Set<String> keySet = ((JSONObject) obj).keySet();
                                            foreachList.addAll(keySet);
                                        }
                                    }
                                }

                                // If we still dont have a list treat it list a string list
                                if (foreachList == null) {
                                    foreachList = new ArrayList<String>();
                                    StrListFunctions.parse(listString, foreachList, listDelim);
                                }
                                loopCount = foreachList.size();

                                if (loopVar.equalsIgnoreCase(""))
                                    error = I18N.getText("lineParser.foreachVarMissing");
                            } catch (ParserException pe) {
                                error = I18N.getText("lineParser.errorProcessingOpt", "FOREACH",
                                        pe.getMessage());
                            }

                            if (error != null)
                                throw doError(error, opts, roll);
                            break;

                        case WHILE:
                            // WHILE(cond [, sep])
                            loopType = LoopType.WHILE;
                            loopCondition = option.getStringParam(0);
                            loopSep = option.getStringParam(1);
                            break;

                        ///////////////////////////////////////////////////
                        // BRANCH OPTIONS
                        ///////////////////////////////////////////////////
                        case IF:
                            // IF(condition)
                            branchType = BranchType.IF;
                            branchCondition = option.getStringParam(0);
                            break;
                        case SWITCH:
                            // SWITCH(condition)
                            branchType = BranchType.SWITCH;
                            branchCondition = option.getObjectParam(0);
                            break;

                        ///////////////////////////////////////////////////
                        // DIALOG AND FRAME OPTIONS
                        ///////////////////////////////////////////////////
                        case FRAME:
                            codeType = CodeType.CODEBLOCK;
                            frameName = option.getParsedParam(0, resolver, tokenInContext).toString();
                            frameOpts = option.getParsedParam(1, resolver, tokenInContext).toString();
                            outputTo = OutputLoc.FRAME;
                            break;
                        case DIALOG:
                            codeType = CodeType.CODEBLOCK;
                            frameName = option.getParsedParam(0, resolver, tokenInContext).toString();
                            frameOpts = option.getParsedParam(1, resolver, tokenInContext).toString();
                            outputTo = OutputLoc.DIALOG;
                            break;
                        ///////////////////////////////////////////////////
                        // CODE OPTIONS
                        ///////////////////////////////////////////////////
                        case MACRO:
                            // MACRO("macroName@location")
                            codeType = CodeType.MACRO;
                            macroName = option.getStringParam(0);
                            break;
                        case CODE:
                            codeType = CodeType.CODEBLOCK;
                            break;
                        ///////////////////////////////////////////////////
                        // MISC OPTIONS
                        ///////////////////////////////////////////////////
                        case TOKEN:
                            if (!isMacroTrusted()) {
                                throw new ParserException(I18N.getText("macro.function.roll.noPerm"));
                            }
                            Token newToken = MapTool.getFrame().getCurrentZoneRenderer().getZone().resolveToken(
                                    option.getParsedParam(0, resolver, tokenInContext).toString());
                            if (newToken != null) {
                                contextTokenStack.push(resolver.getTokenInContext());
                                resolver.setTokenIncontext(newToken);
                            }
                            break;
                        default:
                            // should never happen
                            log.error(I18N.getText("lineParser.badOptionFound", opts, roll));
                            throw doError("lineParser.badOptionFound", opts, roll);
                        }
                    }
                }

                // Now that the options have been dealt with, process the body of the roll.
                // We deal with looping first, then branching, then deliver the output.
                StringBuilder expressionBuilder = new StringBuilder();
                int iteration = 0;
                boolean doLoop = true;
                while (doLoop) {
                    int loopConditionValue;
                    Integer branchConditionValue = null;
                    Object branchConditionParsed = null;

                    // Process loop settings
                    if (iteration > maxLoopIterations) {
                        throw doError("lineParser.tooManyLoops", opts, roll);
                    }

                    if (loopType != LoopType.NO_LOOP) {
                        // We only update roll.count in a loop statement.  This allows simple nested 
                        // statements to inherit roll.count from the outer statement.
                        resolver.setVariable("roll.count", iteration);
                    }

                    switch (loopType) {
                    /*
                     * TODO: If you're adding a new looping option, add a
                     * new case to handle the iteration
                     */
                    case NO_LOOP:
                        if (iteration > 0) { // stop after first iteration
                            doLoop = false;
                        }
                        break;
                    case COUNT:
                        if (iteration == loopCount) {
                            doLoop = false;
                        }
                        break;
                    case FOR:
                        if (iteration != loopCount) {
                            resolver.setVariable(loopVar, new BigDecimal(loopStart + loopStep * iteration));
                        } else {
                            doLoop = false;
                            resolver.setVariable(loopVar, null);
                        }
                        break;
                    case FOREACH:
                        if (iteration != loopCount) {
                            String item = foreachList.get(iteration);
                            resolver.setVariable(loopVar, item);
                        } else {
                            doLoop = false;
                            resolver.setVariable(loopVar, null);
                        }
                        break;
                    case WHILE:
                        // This is a hack to get around a bug with the parser's comparison operators.
                        // The InlineTreeFormatter class in the parser chokes on comparison operators, because they're
                        // not listed in the operator precedence table.
                        //
                        // The workaround is that "non-deterministic" functions fully evaluate their arguments,
                        // so the comparison operators are reduced to a number by the time the buggy code is reached.
                        // The if() function defined in dicelib is such a function, so we use it here to eat
                        // any comparison operators.
                        String hackCondition = (loopCondition == null) ? null
                                : String.format("if(%s, 1, 0)", loopCondition);
                        // Stop loop if the while condition is false
                        try {
                            Result result = parseExpression(resolver, tokenInContext, hackCondition);
                            loopConditionValue = ((Number) result.getValue()).intValue();
                            if (loopConditionValue == 0) {
                                doLoop = false;
                            }
                        } catch (Exception e) {
                            throw doError(I18N.getText("lineParser.invalidWhile", loopCondition), opts, roll);
                        }
                        break;
                    }

                    // Output the loop separator
                    if (doLoop && iteration != 0 && output != Output.NONE) {
                        expressionBuilder.append(parseExpression(resolver, tokenInContext, loopSep).getValue());
                    }

                    if (!doLoop) {
                        break;
                    }

                    iteration++;

                    // Extract the appropriate branch to evaluate.

                    // Evaluate the branch condition/expression
                    if (branchCondition != null) {
                        // This is a similar hack to the one used for the loopCondition above.
                        String hackCondition = (branchCondition == null) ? null : branchCondition.toString();
                        if (branchType == BranchType.IF) {
                            hackCondition = (hackCondition == null) ? null
                                    : String.format("if(%s, 1, 0)", hackCondition);
                        }
                        Result result = null;
                        try {
                            result = parseExpression(resolver, tokenInContext, hackCondition);
                        } catch (Exception e) {
                            throw doError(I18N.getText("lineParser.invalidCondition", branchType.toString(),
                                    branchCondition.toString()), opts, roll);
                        }
                        branchConditionParsed = result.getValue();
                        if (branchConditionParsed instanceof Number) {
                            branchConditionValue = ((Number) branchConditionParsed).intValue();
                        }
                    }

                    // Set up regexes for scanning through the branches.
                    // branchRegex then defines one matcher group for the parseable content of the branch.
                    String rollBranch = roll;
                    String branchRegex, branchSepRegex, branchLastSepRegex;
                    if (codeType != CodeType.CODEBLOCK) {
                        // matches any text not containing a ";" (skipping over strings) 
                        String noCodeRegex = "((?:[^\";]|\"[^\"]*\"|'[^']*')*)";
                        branchRegex = noCodeRegex;
                        branchSepRegex = ";";
                        branchLastSepRegex = ";?"; // The last clause doesn't have to end with a separator
                    } else {
                        // matches text inside braces "{...}", skipping over strings (one level of {} nesting allowed)
                        String codeRegex = "\\{((?:[^{}\"]|\"[^\"]*\"|'[^']*'|\\{(?:[^}\"]|\"[^\"]*\"|'[^']*')*})*)}";
                        branchRegex = codeRegex;
                        branchSepRegex = ";";
                        branchLastSepRegex = ";?"; // The last clause doesn't have to end with a separator
                    }

                    // Extract the branch to use
                    switch (branchType) {
                    /*
                     * TODO: If you're adding a new branching option, add a
                     * new case to extract the branch text
                     */
                    case NO_BRANCH: {
                        // There's only one branch, so our regex is very simple
                        String testRegex = String.format("^\\s*%s\\s*$", branchRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) {
                            rollBranch = testMatcher.group(1);
                        } else {
                            throw doError("lineParser.errorBodyRoll", opts, roll);
                        }
                        break;
                    }
                    case IF: {
                        // IF can have one or two branches.
                        // When there's only one branch and the condition is false, there's no output.
                        if (branchConditionValue == null) {
                            throw doError(I18N.getText("lineParser.invalidIfCond", branchCondition,
                                    branchConditionParsed.toString()), opts, roll);
                        }
                        int whichBranch = (branchConditionValue != 0) ? 0 : 1;
                        String testRegex = String.format("^\\s*%s\\s*(?:%s\\s*%s\\s*%s)?\\s*$", branchRegex,
                                branchSepRegex, branchRegex, branchLastSepRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) { // verifies that roll body is well-formed
                            rollBranch = testMatcher.group(1 + whichBranch);
                            if (rollBranch == null)
                                rollBranch = "''"; // quick-and-dirty way to get no output
                            rollBranch = rollBranch.trim();
                        } else {
                            throw doError("lineParser.ifError", opts, roll);
                        }
                        break;
                    }
                    case SWITCH: {
                        // We augment the branch regex to detect the "case xxx:" or "default:" prefixes,
                        // and search for a match.  An error is thrown if no case match is found.

                        // Regex matches 'default', 'case 123:', 'case "123":', 'case "abc":', but not 'case abc:'
                        branchRegex = "(?:case\\s*\"?((?<!\")(?:\\+|-)?[\\d]+(?!\")|(?<=\")[^\"]*(?=\"))\"?|(default))\\s*:\\s*"
                                + branchRegex;
                        String caseTarget = branchConditionParsed.toString();
                        String testRegex = String.format("^(?:\\s*%s\\s*%s\\s*)*\\s*%s\\s*%s\\s*$", branchRegex,
                                branchSepRegex, branchRegex, branchLastSepRegex);
                        Matcher testMatcher = Pattern.compile(testRegex).matcher(roll);
                        if (testMatcher.find()) { // verifies that roll body is well-formed
                            String scanRegex = String.format("\\s*%s\\s*(?:%s)?", branchRegex, branchSepRegex);
                            Matcher scanMatcher = Pattern.compile(scanRegex).matcher(roll);
                            boolean foundMatch = false;
                            while (!foundMatch && scanMatcher.find()) {
                                String caseLabel = scanMatcher.group(1); // "case (xxx):"
                                String def = scanMatcher.group(2); // "(default):"
                                String branch = scanMatcher.group(3);
                                if (def != null) {
                                    rollBranch = branch.trim();
                                    foundMatch = true;
                                    ;
                                }
                                if (caseLabel != null && caseLabel.matches(caseTarget)) {
                                    rollBranch = branch.trim();
                                    foundMatch = true;
                                }
                            }
                            if (!foundMatch) {
                                doError(I18N.getText("lineParser.switchNoMatch", caseTarget), opts, roll);
                            }
                        } else {
                            doError("lineParser.switchError", opts, roll);
                        }

                        break;
                    }
                    } // end of switch(branchType) statement

                    // Construct the output.  
                    // If a MACRO or CODE block is being used, we default to bare output as in the RESULT style.
                    // The output style NONE is also allowed in these cases.
                    Result result;
                    String output_text;
                    switch (codeType) {
                    case NO_CODE:
                        // If none of the code options are active, any of the formatting options can be used.
                        switch (output) {
                        /*
                         * TODO: If you're adding a new formatting option,
                         * add a new case to build the output
                         */
                        case NONE:
                            parseExpression(resolver, tokenInContext, rollBranch);
                            break;
                        case RESULT:
                            result = parseExpression(resolver, tokenInContext, rollBranch);
                            output_text = result != null ? result.getValue().toString() : "";
                            if (!this.isMacroTrusted()) {
                                output_text = output_text.replaceAll(
                                        "\u00AB|\u00BB|&#171;|&#187;|&laquo;|&raquo;|\036|\037", "");
                            }
                            if (outputOpts.isEmpty()) {
                                expressionBuilder.append(output_text);
                            } else {
                                outputOpts.add("r");
                                expressionBuilder.append(rollString(outputOpts, output_text));
                            }

                            break;
                        case TOOLTIP:
                            String tooltip = rollBranch + " = ";
                            output_text = null;
                            result = parseExpression(resolver, tokenInContext, rollBranch);
                            tooltip += result.getDetailExpression();
                            if (text == null) {
                                output_text = result.getValue().toString();
                            } else {
                                if (!result.getDetailExpression().equals(result.getValue().toString())) {
                                    tooltip += " = " + result.getValue();
                                }
                                resolver.setVariable("roll.result", result.getValue());
                                output_text = parseExpression(resolver, tokenInContext, text).getValue()
                                        .toString();
                            }
                            tooltip = tooltip.replaceAll("'", "&#39;");
                            expressionBuilder.append(
                                    output_text != null ? rollString(outputOpts, tooltip, output_text) : "");
                            break;
                        case EXPANDED:
                            expressionBuilder.append(rollString(outputOpts,
                                    rollBranch + " = " + expandRoll(resolver, tokenInContext, rollBranch)));
                            break;
                        case UNFORMATTED:
                            output_text = rollBranch + " = " + expandRoll(resolver, tokenInContext, rollBranch);

                            // Escape quotes so that the result can be used in a title attribute
                            output_text = output_text.replaceAll("'", "&#39;");
                            output_text = output_text.replaceAll("\"", "&#34;");

                            expressionBuilder.append(rollString(outputOpts, output_text));
                        } // end of switch(output) statement
                        break; // end of case NO_CODE in switch(codeType) statement
                    /*
                     * TODO: If you're adding a new code option, add a new
                     * case to execute the code
                     */
                    case MACRO:
                        // [MACRO("macroName@location"): args]
                        result = parseExpression(resolver, tokenInContext, macroName);
                        String callName = result.getValue().toString();
                        result = parseExpression(resolver, tokenInContext, rollBranch);
                        String macroArgs = result.getValue().toString();
                        output_text = runMacro(resolver, tokenInContext, callName, macroArgs);
                        if (output != Output.NONE) {
                            expressionBuilder.append(output_text);
                        }
                        resolver.setVariable("roll.count", iteration); // reset this because called code might change it
                        break;

                    case CODEBLOCK:
                        output_text = runMacroBlock(resolver, tokenInContext, rollBranch);
                        resolver.setVariable("roll.count", iteration); // reset this because called code might change it
                        if (output != Output.NONE) {
                            expressionBuilder.append(output_text);
                        }
                        break;
                    }
                }
                switch (outputTo) {
                case FRAME:
                    HTMLFrameFactory.show(frameName, true, frameOpts, expressionBuilder.toString());
                    break;
                case DIALOG:
                    HTMLFrameFactory.show(frameName, false, frameOpts, expressionBuilder.toString());
                    break;
                case CHAT:
                    builder.append(expressionBuilder);
                    break;
                }

                // Revert to our previous token if [token(): ] was used
                if (contextTokenStack.size() > 0) {
                    resolver.setTokenIncontext(contextTokenStack.pop());
                }
            } else if (match.getMatch().startsWith("{")) {
                roll = match.getRoll();
                Result result = parseExpression(resolver, tokenInContext, roll);
                if (isMacroTrusted()) {
                    builder.append(result != null ? result.getValue().toString() : "");
                } else {
                    builder.append(result != null ? result.getValue().toString()
                            .replaceAll("\u00AB|\u00BB|&#171;|&#187;|&laquo;|&raquo;|\036|\037", "") : "");
                }
            }
        }
        builder.append(line.substring(start));
        return builder.toString();
    } catch (AbortFunctionException e) {
        // do nothing; this exception will never generate any output
        // throw doError("macroExecutionAbort", opts == null ? "" : opts, roll == null ? line : roll);
        throw e;
    } catch (AssertFunctionException e) {
        // do nothing; this exception will never generate any output
        // throw doError("macroExecutionAssert", opts == null ? "" : opts, roll == null ? line : roll);
        throw e;
    } catch (ParserException e) {
        // do nothing, jut pass message back up
        throw e;
    } catch (Exception e) {
        log.info(line, e);
        throw doError("lineParser.errorBodyRoll", opts == null ? "" : opts, roll == null ? line : roll);
    } finally {
        exitContext();
        if (resolverInitialized) {
            // This is the top level call, time to clean up
            resolver.flush();
        }
        // If we have exited the last context let the html frame we have (potentially)
        // updated a token.
        if (contextStackEmpty()) {
            HTMLFrameFactory.tokenChanged(tokenInContext);
        }
        MapTool.getFrame().refresh(); // Repaint incase macros changed anything. 
    }
}

From source file:imitationNLG.SFX.java

public Instance createAttrInstance(String predicate, ArrayList<String> previousGeneratedAttrs,
        ArrayList<Action> previousGeneratedWords, TObjectDoubleHashMap<String> costs,
        HashSet<String> attrValuesAlreadyMentioned, HashSet<String> attrValuesToBeMentioned,
        MeaningRepresentation MR, HashMap<String, HashSet<String>> availableAttributeActions) {
    TObjectDoubleHashMap<String> generalFeatures = new TObjectDoubleHashMap<>();
    HashMap<String, TObjectDoubleHashMap<String>> valueSpecificFeatures = new HashMap<>();
    for (String action : availableAttributeActions.get(predicate)) {
        valueSpecificFeatures.put(action, new TObjectDoubleHashMap<String>());
    }/*from  www .j  ava  2 s.c  o  m*/

    ArrayList<String> mentionedAttrValues = new ArrayList<>();
    for (String attrValue : previousGeneratedAttrs) {
        if (!attrValue.equals(SFX.TOKEN_END) && !attrValue.equals(SFX.TOKEN_START)) {
            mentionedAttrValues.add(attrValue);
        }
    }

    for (int j = 1; j <= 1; j++) {
        String previousAttrValue = "@@";
        if (mentionedAttrValues.size() - j >= 0) {
            previousAttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - j).trim();
        }
        generalFeatures.put("feature_attrValue_" + j + "_" + previousAttrValue, 1.0);
    }
    //Word N-Grams
    String prevAttrValue = "@@";
    if (mentionedAttrValues.size() - 1 >= 0) {
        prevAttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 1).trim();
    }
    String prev2AttrValue = "@@";
    if (mentionedAttrValues.size() - 2 >= 0) {
        prev2AttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 2).trim();
    }
    String prev3AttrValue = "@@";
    if (mentionedAttrValues.size() - 3 >= 0) {
        prev3AttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 3).trim();
    }
    String prev4AttrValue = "@@";
    if (mentionedAttrValues.size() - 4 >= 0) {
        prev4AttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 4).trim();
    }
    String prev5AttrValue = "@@";
    if (mentionedAttrValues.size() - 5 >= 0) {
        prev5AttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 5).trim();
    }

    String prevBigramAttrValue = prev2AttrValue + "|" + prevAttrValue;
    String prevTrigramAttrValue = prev3AttrValue + "|" + prev2AttrValue + "|" + prevAttrValue;
    String prev4gramAttrValue = prev4AttrValue + "|" + prev3AttrValue + "|" + prev2AttrValue + "|"
            + prevAttrValue;
    String prev5gramAttrValue = prev5AttrValue + "|" + prev4AttrValue + "|" + prev3AttrValue + "|"
            + prev2AttrValue + "|" + prevAttrValue;
    generalFeatures.put("feature_attrValue_bigram_" + prevBigramAttrValue, 1.0);
    generalFeatures.put("feature_attrValue_trigram_" + prevTrigramAttrValue, 1.0);
    generalFeatures.put("feature_attrValue_4gram_" + prev4gramAttrValue, 1.0);
    generalFeatures.put("feature_attrValue_5gram_" + prev5gramAttrValue, 1.0);

    /*String bigramAttrValue54 = prev5AttrValue + "|" + prev4AttrValue;
     String bigramAttrValue43 = prev4AttrValue + "|" + prev3AttrValue;
     String bigramAttrValue32 = prev3AttrValue + "|" + prev2AttrValue;
     generalFeatures.put("feature_attrValue_bigramAttrValue54_" + bigramAttrValue54, 1.0);
     generalFeatures.put("feature_attrValue_bigramAttrValue43_" + bigramAttrValue43, 1.0);
     generalFeatures.put("feature_attrValue_bigramAttrValue32_" + bigramAttrValue32, 1.0);
            
     String bigramAttrValueSkip53 = prev5AttrValue + "|" + prev3AttrValue;
     String bigramAttrValueSkip42 = prev4AttrValue + "|" + prev2AttrValue;
     String bigramAttrValueSkip31 = prev3AttrValue + "|" + prevAttrValue;
     generalFeatures.put("feature_attrValue_bigramAttrValueSkip53_" + bigramAttrValueSkip53, 1.0);
     generalFeatures.put("feature_attrValue_bigramAttrValueSkip42_" + bigramAttrValueSkip42, 1.0);
     generalFeatures.put("feature_attrValue_bigramAttrValueSkip31_" + bigramAttrValueSkip31, 1.0);
            
     String trigramAttrValue543 = prev5AttrValue + "|" + prev4AttrValue + "|" + prev3AttrValue;
     String trigramAttrValue432 = prev4AttrValue + "|" + prev3AttrValue + "|" + prev2AttrValue;
     generalFeatures.put("feature_attrValue_trigramAttrValue543_" + trigramAttrValue543, 1.0);
     generalFeatures.put("feature_attrValue_trigramAttrValue432_" + trigramAttrValue432, 1.0);
            
     String trigramAttrValueSkip542 = prev5AttrValue + "|" + prev4AttrValue + "|" + prev2AttrValue;
     String trigramAttrValueSkip532 = prev5AttrValue + "|" + prev3AttrValue + "|" + prev2AttrValue;
     String trigramAttrValueSkip431 = prev4AttrValue + "|" + prev3AttrValue + "|" + prevAttrValue;
     String trigramAttrValueSkip421 = prev4AttrValue + "|" + prev2AttrValue + "|" + prevAttrValue;
     generalFeatures.put("feature_attrValue_trigramAttrValueSkip542_" + trigramAttrValueSkip542, 1.0);
     generalFeatures.put("feature_attrValue_trigramAttrValueSkip532_" + trigramAttrValueSkip532, 1.0);
     generalFeatures.put("feature_attrValue_trigramAttrValueSkip431_" + trigramAttrValueSkip431, 1.0);
     generalFeatures.put("feature_attrValue_trigramAttrValueSkip421_" + trigramAttrValueSkip421, 1.0);*/
    //Word Positions
    //features.put("feature_pos:", w);
    //If arguments have been generated or not
    for (int i = 0; i < mentionedAttrValues.size(); i++) {
        generalFeatures.put("feature_attrValue_allreadyMentioned_" + mentionedAttrValues.get(i), 1.0);
    }
    //If arguments should still be generated or not
    for (String attrValue : attrValuesToBeMentioned) {
        generalFeatures.put("feature_attrValue_toBeMentioned_" + attrValue, 1.0);
    }
    //Which attrs are in the MR and which are not
    for (String attribute : availableAttributeActions.get(predicate)) {
        if (MR.getAttributes().keySet().contains(attribute)) {
            generalFeatures.put("feature_attr_inMR_" + attribute, 1.0);
        } else {
            generalFeatures.put("feature_attr_notInMR_" + attribute, 1.0);
        }
    }

    ArrayList<String> mentionedAttrs = new ArrayList<>();
    for (int i = 0; i < mentionedAttrValues.size(); i++) {
        String attr = mentionedAttrValues.get(i);
        if (attr.contains("=")) {
            attr = mentionedAttrValues.get(i).substring(0, mentionedAttrValues.get(i).indexOf('='));
        }
        //if (mentionedAttrs.isEmpty()) {
        //mentionedAttrs.add(attr);
        //} else if (!mentionedAttrs.get(mentionedAttrs.size() - 1).equals(attr)) {
        mentionedAttrs.add(attr);
        //}
    }
    HashSet<String> attrsToBeMentioned = new HashSet<>();
    for (String attrValue : attrValuesToBeMentioned) {
        String attr = attrValue;
        if (attr.contains("=")) {
            attr = attrValue.substring(0, attrValue.indexOf('='));
        }
        attrsToBeMentioned.add(attr);
    }

    for (int j = 1; j <= 1; j++) {
        String previousAttr = "";
        if (mentionedAttrs.size() - j >= 0) {
            previousAttr = mentionedAttrs.get(mentionedAttrs.size() - j).trim();
        }
        if (!previousAttr.isEmpty()) {
            generalFeatures.put("feature_attr_" + j + "_" + previousAttr, 1.0);
        } else {
            generalFeatures.put("feature_attr_" + j + "_@@", 1.0);
        }
    }
    //Word N-Grams
    String prevAttr = "@@";
    if (mentionedAttrs.size() - 1 >= 0) {
        prevAttr = mentionedAttrs.get(mentionedAttrs.size() - 1).trim();
    }
    String prev2Attr = "@@";
    if (mentionedAttrs.size() - 2 >= 0) {
        prev2Attr = mentionedAttrs.get(mentionedAttrs.size() - 2).trim();
    }
    String prev3Attr = "@@";
    if (mentionedAttrs.size() - 3 >= 0) {
        prev3Attr = mentionedAttrs.get(mentionedAttrs.size() - 3).trim();
    }
    String prev4Attr = "@@";
    if (mentionedAttrs.size() - 4 >= 0) {
        prev4Attr = mentionedAttrs.get(mentionedAttrs.size() - 4).trim();
    }
    String prev5Attr = "@@";
    if (mentionedAttrs.size() - 5 >= 0) {
        prev5Attr = mentionedAttrs.get(mentionedAttrs.size() - 5).trim();
    }

    String prevBigramAttr = prev2Attr + "|" + prevAttr;
    String prevTrigramAttr = prev3Attr + "|" + prev2Attr + "|" + prevAttr;
    String prev4gramAttr = prev4Attr + "|" + prev3Attr + "|" + prev2Attr + "|" + prevAttr;
    String prev5gramAttr = prev5Attr + "|" + prev4Attr + "|" + prev3Attr + "|" + prev2Attr + "|" + prevAttr;

    generalFeatures.put("feature_attr_bigram_" + prevBigramAttr, 1.0);
    generalFeatures.put("feature_attr_trigram_" + prevTrigramAttr, 1.0);
    generalFeatures.put("feature_attr_4gram_" + prev4gramAttr, 1.0);
    generalFeatures.put("feature_attr_5gram_" + prev5gramAttr, 1.0);

    /*String bigramAttr54 = prev5Attr + "|" + prev4Attr;
     String bigramAttr43 = prev4Attr + "|" + prev3Attr;
     String bigramAttr32 = prev3Attr + "|" + prev2Attr;
     generalFeatures.put("feature_attr_bigramAttr54_" + bigramAttr54, 1.0);
     generalFeatures.put("feature_attr_bigramAttr43_" + bigramAttr43, 1.0);
     generalFeatures.put("feature_attr_bigramAttr32_" + bigramAttr32, 1.0);
            
     String bigramAttrSkip53 = prev5Attr + "|" + prev3Attr;
     String bigramAttrSkip42 = prev4Attr + "|" + prev2Attr;
     String bigramAttrSkip31 = prev3Attr + "|" + prevAttr;
     generalFeatures.put("feature_attr_bigramAttrSkip53_" + bigramAttrSkip53, 1.0);
     generalFeatures.put("feature_attr_bigramAttrSkip42_" + bigramAttrSkip42, 1.0);
     generalFeatures.put("feature_attr_bigramAttrSkip31_" + bigramAttrSkip31, 1.0);
            
     String trigramAttr543 = prev5Attr + "|" + prev4Attr + "|" + prev3Attr;
     String trigramAttr432 = prev4Attr + "|" + prev3Attr + "|" + prev2Attr;
     generalFeatures.put("feature_attr_trigramAttr543_" + trigramAttr543, 1.0);
     generalFeatures.put("feature_attr_trigramAttr432_" + trigramAttr432, 1.0);
            
     String trigramAttrSkip542 = prev5Attr + "|" + prev4Attr + "|" + prev2Attr;
     String trigramAttrSkip532 = prev5Attr + "|" + prev3Attr + "|" + prev2Attr;
     String trigramAttrSkip431 = prev4Attr + "|" + prev3Attr + "|" + prevAttr;
     String trigramAttrSkip421 = prev4Attr + "|" + prev2Attr + "|" + prevAttr;
     generalFeatures.put("feature_attr_trigramAttrSkip542_" + trigramAttrSkip542, 1.0);
     generalFeatures.put("feature_attr_trigramAttrSkip532_" + trigramAttrSkip532, 1.0);
     generalFeatures.put("feature_attr_trigramAttrSkip431_" + trigramAttrSkip431, 1.0);
     generalFeatures.put("feature_attr_trigramAttrSkip421_" + trigramAttrSkip421, 1.0);*/
    ArrayList<Action> generatedWords = new ArrayList<>();
    ArrayList<Action> generatedWordsInPreviousAttrValue = new ArrayList<>();
    if (!mentionedAttrValues.isEmpty()) {
        String previousAttrValue = mentionedAttrValues.get(mentionedAttrValues.size() - 1);
        for (int i = 0; i < previousGeneratedWords.size(); i++) {
            Action a = previousGeneratedWords.get(i);
            if (!a.getWord().equals(SFX.TOKEN_START) && !a.getWord().equals(SFX.TOKEN_END)) {
                generatedWords.add(a);
                if (a.getAttribute().equals(previousAttrValue)) {
                    generatedWordsInPreviousAttrValue.add(a);
                }
            }
        }
    }
    //Previous word features
    for (int j = 1; j <= 1; j++) {
        String previousWord = "@@";
        if (generatedWords.size() - j >= 0) {
            previousWord = generatedWords.get(generatedWords.size() - j).getWord().trim();
        }
        generalFeatures.put("feature_word_" + j + "_" + previousWord.toLowerCase(), 1.0);
    }
    String prevWord = "@@";
    if (generatedWords.size() - 1 >= 0) {
        prevWord = generatedWords.get(generatedWords.size() - 1).getWord().trim();
    }
    String prev2Word = "@@";
    if (generatedWords.size() - 2 >= 0) {
        prev2Word = generatedWords.get(generatedWords.size() - 2).getWord().trim();
    }
    String prev3Word = "@@";
    if (generatedWords.size() - 3 >= 0) {
        prev3Word = generatedWords.get(generatedWords.size() - 3).getWord().trim();
    }
    String prev4Word = "@@";
    if (generatedWords.size() - 4 >= 0) {
        prev4Word = generatedWords.get(generatedWords.size() - 4).getWord().trim();
    }
    String prev5Word = "@@";
    if (generatedWords.size() - 5 >= 0) {
        prev5Word = generatedWords.get(generatedWords.size() - 5).getWord().trim();
    }

    String prevBigram = prev2Word + "|" + prevWord;
    String prevTrigram = prev3Word + "|" + prev2Word + "|" + prevWord;
    String prev4gram = prev4Word + "|" + prev3Word + "|" + prev2Word + "|" + prevWord;
    String prev5gram = prev5Word + "|" + prev4Word + "|" + prev3Word + "|" + prev2Word + "|" + prevWord;

    generalFeatures.put("feature_word_bigram_" + prevBigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_word_trigram_" + prevTrigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_word_4gram_" + prev4gram.toLowerCase(), 1.0);
    generalFeatures.put("feature_word_5gram_" + prev5gram.toLowerCase(), 1.0);

    /*String bigramWord54 = prev5Word + "|" + prev4Word;
     String bigramWord43 = prev4Word + "|" + prev3Word;
     String bigramWord32 = prev3Word + "|" + prev2Word;
     generalFeatures.put("feature_word_bigramWord54_" + bigramWord54, 1.0);
     generalFeatures.put("feature_word_bigramWord43_" + bigramWord43, 1.0);
     generalFeatures.put("feature_word_bigramWord32_" + bigramWord32, 1.0);
            
     String bigramWordSkip53 = prev5Word + "|" + prev3Word;
     String bigramWordSkip42 = prev4Word + "|" + prev2Word;
     String bigramWordSkip31 = prev3Word + "|" + prevWord;
     generalFeatures.put("feature_word_bigramWordSkip53_" + bigramWordSkip53, 1.0);
     generalFeatures.put("feature_word_bigramWordSkip42_" + bigramWordSkip42, 1.0);
     generalFeatures.put("feature_word_bigramWordSkip31_" + bigramWordSkip31, 1.0);
            
     String trigramWord543 = prev5Word + "|" + prev4Word + "|" + prev3Word;
     String trigramWord432 = prev4Word + "|" + prev3Word + "|" + prev2Word;
     generalFeatures.put("feature_word_trigramWord543_" + trigramWord543, 1.0);
     generalFeatures.put("feature_word_trigramWord432_" + trigramWord432, 1.0);
            
     String trigramWordSkip542 = prev5Word + "|" + prev4Word + "|" + prev2Word;
     String trigramWordSkip532 = prev5Word + "|" + prev3Word + "|" + prev2Word;
     String trigramWordSkip431 = prev4Word + "|" + prev3Word + "|" + prevWord;
     String trigramWordSkip421 = prev4Word + "|" + prev2Word + "|" + prevWord;
     generalFeatures.put("feature_word_trigramWordSkip542_" + trigramWordSkip542, 1.0);
     generalFeatures.put("feature_word_trigramWordSkip532_" + trigramWordSkip532, 1.0);
     generalFeatures.put("feature_word_trigramWordSkip431_" + trigramWordSkip431, 1.0);
     generalFeatures.put("feature_word_trigramWordSkip421_" + trigramWordSkip421, 1.0);*/
    //Previous word in same as current attrValue features
    for (int j = 1; j <= 1; j++) {
        String previousCurrentAttrValueWord = "@@";
        if (generatedWordsInPreviousAttrValue.size() - j >= 0) {
            previousCurrentAttrValueWord = generatedWordsInPreviousAttrValue
                    .get(generatedWordsInPreviousAttrValue.size() - j).getWord().trim();
        }
        generalFeatures.put(
                "feature_currentAttrValueWord_" + j + "_" + previousCurrentAttrValueWord.toLowerCase(), 1.0);
    }
    String prevCurrentAttrValueWord = "@@";
    if (generatedWordsInPreviousAttrValue.size() - 1 >= 0) {
        prevCurrentAttrValueWord = generatedWordsInPreviousAttrValue
                .get(generatedWordsInPreviousAttrValue.size() - 1).getWord().trim();
    }
    String prev2CurrentAttrValueWord = "@@";
    if (generatedWordsInPreviousAttrValue.size() - 2 >= 0) {
        prev2CurrentAttrValueWord = generatedWordsInPreviousAttrValue
                .get(generatedWordsInPreviousAttrValue.size() - 2).getWord().trim();
    }
    String prev3CurrentAttrValueWord = "@@";
    if (generatedWordsInPreviousAttrValue.size() - 3 >= 0) {
        prev3CurrentAttrValueWord = generatedWordsInPreviousAttrValue
                .get(generatedWordsInPreviousAttrValue.size() - 3).getWord().trim();
    }
    String prev4CurrentAttrValueWord = "@@";
    if (generatedWordsInPreviousAttrValue.size() - 4 >= 0) {
        prev4CurrentAttrValueWord = generatedWordsInPreviousAttrValue
                .get(generatedWordsInPreviousAttrValue.size() - 4).getWord().trim();
    }
    String prev5CurrentAttrValueWord = "@@";
    if (generatedWordsInPreviousAttrValue.size() - 5 >= 0) {
        prev5CurrentAttrValueWord = generatedWordsInPreviousAttrValue
                .get(generatedWordsInPreviousAttrValue.size() - 5).getWord().trim();
    }

    String prevCurrentAttrValueBigram = prev2CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;
    String prevCurrentAttrValueTrigram = prev3CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord + "|"
            + prevCurrentAttrValueWord;
    String prevCurrentAttrValue4gram = prev4CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord + "|"
            + prev2CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;
    String prevCurrentAttrValue5gram = prev5CurrentAttrValueWord + "|" + prev4CurrentAttrValueWord + "|"
            + prev3CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;

    generalFeatures.put("feature_previousAttrValueWord_bigram_" + prevCurrentAttrValueBigram.toLowerCase(),
            1.0);
    generalFeatures.put("feature_previousAttrValueWord_trigram_" + prevCurrentAttrValueTrigram.toLowerCase(),
            1.0);
    generalFeatures.put("feature_previousAttrValueWord_4gram_" + prevCurrentAttrValue4gram.toLowerCase(), 1.0);
    generalFeatures.put("feature_previousAttrValueWord_5gram_" + prevCurrentAttrValue5gram.toLowerCase(), 1.0);

    /*String bigramCurrentAttrValueWord54 = prev5CurrentAttrValueWord + "|" + prev4CurrentAttrValueWord;
     String bigramCurrentAttrValueWord43 = prev4CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord;
     String bigramCurrentAttrValueWord32 = prev3CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord;
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWord54_" + bigramCurrentAttrValueWord54, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWord43_" + bigramCurrentAttrValueWord43, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWord32_" + bigramCurrentAttrValueWord32, 1.0);
            
     String bigramCurrentAttrValueWordSkip53 = prev5CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord;
     String bigramCurrentAttrValueWordSkip42 = prev4CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord;
     String bigramCurrentAttrValueWordSkip31 = prev3CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWordSkip53_" + bigramCurrentAttrValueWordSkip53, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWordSkip42_" + bigramCurrentAttrValueWordSkip42, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_bigramCurrentAttrValueWordSkip31_" + bigramCurrentAttrValueWordSkip31, 1.0);
            
     String trigramCurrentAttrValueWord543 = prev5CurrentAttrValueWord + "|" + prev4CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord;
     String trigramCurrentAttrValueWord432 = prev4CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord;
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWord543_" + trigramCurrentAttrValueWord543, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWord432_" + trigramCurrentAttrValueWord432, 1.0);
            
     String trigramCurrentAttrValueWordSkip542 = prev5CurrentAttrValueWord + "|" + prev4CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord;
     String trigramCurrentAttrValueWordSkip532 = prev5CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord;
     String trigramCurrentAttrValueWordSkip431 = prev4CurrentAttrValueWord + "|" + prev3CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;
     String trigramCurrentAttrValueWordSkip421 = prev4CurrentAttrValueWord + "|" + prev2CurrentAttrValueWord + "|" + prevCurrentAttrValueWord;
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWordSkip542_" + trigramCurrentAttrValueWordSkip542, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWordSkip532_" + trigramCurrentAttrValueWordSkip532, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWordSkip431_" + trigramCurrentAttrValueWordSkip431, 1.0);
     generalFeatures.put("feature_previousAttrValueWord_trigramCurrentAttrValueWordSkip421_" + trigramCurrentAttrValueWordSkip421, 1.0);*/
    //Previous Attr|Word features
    for (int j = 1; j <= 1; j++) {
        String previousAttrWord = "@@";
        if (generatedWords.size() - j >= 0) {
            if (generatedWords.get(generatedWords.size() - j).getAttribute().contains("=")) {
                previousAttrWord = generatedWords.get(generatedWords.size() - j).getAttribute().trim()
                        .substring(0, generatedWords.get(generatedWords.size() - j).getAttribute().indexOf('='))
                        + "|" + generatedWords.get(generatedWords.size() - j).getWord().trim();
            } else {
                previousAttrWord = generatedWords.get(generatedWords.size() - j).getAttribute().trim() + "|"
                        + generatedWords.get(generatedWords.size() - j).getWord().trim();
            }
        }
        generalFeatures.put("feature_attrWord_" + j + "_" + previousAttrWord.toLowerCase(), 1.0);
    }
    String prevAttrWord = "@@";
    if (generatedWords.size() - 1 >= 0) {
        if (generatedWords.get(generatedWords.size() - 1).getAttribute().contains("=")) {
            prevAttrWord = generatedWords.get(generatedWords.size() - 1).getAttribute().trim().substring(0,
                    generatedWords.get(generatedWords.size() - 1).getAttribute().indexOf('=')) + ":"
                    + generatedWords.get(generatedWords.size() - 1).getWord().trim();
        } else {
            prevAttrWord = generatedWords.get(generatedWords.size() - 1).getAttribute().trim() + ":"
                    + generatedWords.get(generatedWords.size() - 1).getWord().trim();

        }
    }
    String prev2AttrWord = "@@";
    if (generatedWords.size() - 2 >= 0) {
        if (generatedWords.get(generatedWords.size() - 2).getAttribute().contains("=")) {
            prev2AttrWord = generatedWords.get(generatedWords.size() - 2).getAttribute().trim().substring(0,
                    generatedWords.get(generatedWords.size() - 2).getAttribute().indexOf('=')) + ":"
                    + generatedWords.get(generatedWords.size() - 2).getWord().trim();
        } else {
            prev2AttrWord = generatedWords.get(generatedWords.size() - 2).getAttribute().trim() + ":"
                    + generatedWords.get(generatedWords.size() - 2).getWord().trim();
        }
    }
    String prev3AttrWord = "@@";
    if (generatedWords.size() - 3 >= 0) {
        if (generatedWords.get(generatedWords.size() - 3).getAttribute().contains("=")) {
            prev3AttrWord = generatedWords.get(generatedWords.size() - 3).getAttribute().trim().substring(0,
                    generatedWords.get(generatedWords.size() - 3).getAttribute().indexOf('=')) + ":"
                    + generatedWords.get(generatedWords.size() - 3).getWord().trim();
        } else {
            prev3AttrWord = generatedWords.get(generatedWords.size() - 3).getAttribute().trim() + ":"
                    + generatedWords.get(generatedWords.size() - 3).getWord().trim();
        }
    }
    String prev4AttrWord = "@@";
    if (generatedWords.size() - 4 >= 0) {
        if (generatedWords.get(generatedWords.size() - 4).getAttribute().contains("=")) {
            prev4AttrWord = generatedWords.get(generatedWords.size() - 4).getAttribute().trim().substring(0,
                    generatedWords.get(generatedWords.size() - 4).getAttribute().indexOf('=')) + ":"
                    + generatedWords.get(generatedWords.size() - 4).getWord().trim();
        } else {
            prev4AttrWord = generatedWords.get(generatedWords.size() - 4).getAttribute().trim() + ":"
                    + generatedWords.get(generatedWords.size() - 4).getWord().trim();
        }
    }
    String prev5AttrWord = "@@";
    if (generatedWords.size() - 5 >= 0) {
        if (generatedWords.get(generatedWords.size() - 5).getAttribute().contains("=")) {
            prev5AttrWord = generatedWords.get(generatedWords.size() - 5).getAttribute().trim().substring(0,
                    generatedWords.get(generatedWords.size() - 5).getAttribute().indexOf('=')) + ":"
                    + generatedWords.get(generatedWords.size() - 5).getWord().trim();
        } else {
            prev5AttrWord = generatedWords.get(generatedWords.size() - 5).getAttribute().trim() + ":"
                    + generatedWords.get(generatedWords.size() - 5).getWord().trim();
        }
    }

    String prevAttrWordBigram = prev2AttrWord + "|" + prevAttrWord;
    String prevAttrWordTrigram = prev3AttrWord + "|" + prev2AttrWord + "|" + prevAttrWord;
    String prevAttrWord4gram = prev4AttrWord + "|" + prev3AttrWord + "|" + prev2AttrWord + "|" + prevAttrWord;
    String prevAttrWord5gram = prev5AttrWord + "|" + prev4AttrWord + "|" + prev3AttrWord + "|" + prev2AttrWord
            + "|" + prevAttrWord;

    generalFeatures.put("feature_attrWord_bigram_" + prevAttrWordBigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrWord_trigram_" + prevAttrWordTrigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrWord_4gram_" + prevAttrWord4gram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrWord_5gram_" + prevAttrWord5gram.toLowerCase(), 1.0);

    /*String bigramAttrWord54 = prev5AttrWord + "|" + prev4AttrWord;
     String bigramAttrWord43 = prev4AttrWord + "|" + prev3AttrWord;
     String bigramAttrWord32 = prev3AttrWord + "|" + prev2AttrWord;
     generalFeatures.put("feature_attrWord_bigramAttrWord54_" + bigramAttrWord54, 1.0);
     generalFeatures.put("feature_attrWord_bigramAttrWord43_" + bigramAttrWord43, 1.0);
     generalFeatures.put("feature_attrWord_bigramAttrWord32_" + bigramAttrWord32, 1.0);
            
     String bigramAttrWordSkip53 = prev5AttrWord + "|" + prev3AttrWord;
     String bigramAttrWordSkip42 = prev4AttrWord + "|" + prev2AttrWord;
     String bigramAttrWordSkip31 = prev3AttrWord + "|" + prevAttrWord;
     generalFeatures.put("feature_attrWord_bigramAttrWordSkip53_" + bigramAttrWordSkip53, 1.0);
     generalFeatures.put("feature_attrWord_bigramAttrWordSkip42_" + bigramAttrWordSkip42, 1.0);
     generalFeatures.put("feature_attrWord_bigramAttrWordSkip31_" + bigramAttrWordSkip31, 1.0);
            
     String trigramAttrWord543 = prev5AttrWord + "|" + prev4AttrWord + "|" + prev3AttrWord;
     String trigramAttrWord432 = prev4AttrWord + "|" + prev3AttrWord + "|" + prev2AttrWord;
     generalFeatures.put("feature_attrWord_trigramAttrWord543_" + trigramAttrWord543, 1.0);
     generalFeatures.put("feature_attrWord_trigramAttrWord432_" + trigramAttrWord432, 1.0);
            
     String trigramAttrWordSkip542 = prev5AttrWord + "|" + prev4AttrWord + "|" + prev2AttrWord;
     String trigramAttrWordSkip532 = prev5AttrWord + "|" + prev3AttrWord + "|" + prev2AttrWord;
     String trigramAttrWordSkip431 = prev4AttrWord + "|" + prev3AttrWord + "|" + prevAttrWord;
     String trigramAttrWordSkip421 = prev4AttrWord + "|" + prev2AttrWord + "|" + prevAttrWord;
     generalFeatures.put("feature_attrWord_trigramAttrWordSkip542_" + trigramAttrWordSkip542, 1.0);
     generalFeatures.put("feature_attrWord_trigramAttrWordSkip532_" + trigramAttrWordSkip532, 1.0);
     generalFeatures.put("feature_attrWord_trigramAttrWordSkip431_" + trigramAttrWordSkip431, 1.0);
     generalFeatures.put("feature_attrWord_trigramAttrWordSkip421_" + trigramAttrWordSkip421, 1.0);*/
    //Previous AttrValue|Word features
    for (int j = 1; j <= 1; j++) {
        String previousAttrWord = "@@";
        if (generatedWords.size() - j >= 0) {
            previousAttrWord = generatedWords.get(generatedWords.size() - j).getAttribute().trim() + "|"
                    + generatedWords.get(generatedWords.size() - j).getWord().trim();
        }
        generalFeatures.put("feature_attrValueWord_" + j + "_" + previousAttrWord.toLowerCase(), 1.0);
    }
    String prevAttrValueWord = "@@";
    if (generatedWords.size() - 1 >= 0) {
        prevAttrValueWord = generatedWords.get(generatedWords.size() - 1).getAttribute().trim() + ":"
                + generatedWords.get(generatedWords.size() - 1).getWord().trim();
    }
    String prev2AttrValueWord = "@@";
    if (generatedWords.size() - 2 >= 0) {
        prev2AttrValueWord = generatedWords.get(generatedWords.size() - 2).getAttribute().trim() + ":"
                + generatedWords.get(generatedWords.size() - 2).getWord().trim();
    }
    String prev3AttrValueWord = "@@";
    if (generatedWords.size() - 3 >= 0) {
        prev3AttrValueWord = generatedWords.get(generatedWords.size() - 3).getAttribute().trim() + ":"
                + generatedWords.get(generatedWords.size() - 3).getWord().trim();
    }
    String prev4AttrValueWord = "@@";
    if (generatedWords.size() - 4 >= 0) {
        prev4AttrValueWord = generatedWords.get(generatedWords.size() - 4).getAttribute().trim() + ":"
                + generatedWords.get(generatedWords.size() - 4).getWord().trim();
    }
    String prev5AttrValueWord = "@@";
    if (generatedWords.size() - 5 >= 0) {
        prev5AttrValueWord = generatedWords.get(generatedWords.size() - 5).getAttribute().trim() + ":"
                + generatedWords.get(generatedWords.size() - 5).getWord().trim();
    }

    String prevAttrValueWordBigram = prev2AttrValueWord + "|" + prevAttrValueWord;
    String prevAttrValueWordTrigram = prev3AttrValueWord + "|" + prev2AttrValueWord + "|" + prevAttrValueWord;
    String prevAttrValueWord4gram = prev4AttrValueWord + "|" + prev3AttrValueWord + "|" + prev2AttrValueWord
            + "|" + prevAttrValueWord;
    String prevAttrValueWord5gram = prev5AttrValueWord + "|" + prev4AttrValueWord + "|" + prev3AttrValueWord
            + "|" + prev2AttrValueWord + "|" + prevAttrValueWord;

    generalFeatures.put("feature_attrValueWord_bigram_" + prevAttrValueWordBigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrValueWord_trigram_" + prevAttrValueWordTrigram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrValueWord_4gram_" + prevAttrValueWord4gram.toLowerCase(), 1.0);
    generalFeatures.put("feature_attrValueWord_5gram_" + prevAttrValueWord5gram.toLowerCase(), 1.0);

    /*String bigramAttrValueWord54 = prev5AttrValueWord + "|" + prev4AttrValueWord;
     String bigramAttrValueWord43 = prev4AttrValueWord + "|" + prev3AttrValueWord;
     String bigramAttrValueWord32 = prev3AttrValueWord + "|" + prev2AttrValueWord;
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWord54_" + bigramAttrValueWord54, 1.0);
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWord43_" + bigramAttrValueWord43, 1.0);
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWord32_" + bigramAttrValueWord32, 1.0);
            
     String bigramAttrValueWordSkip53 = prev5AttrValueWord + "|" + prev3AttrValueWord;
     String bigramAttrValueWordSkip42 = prev4AttrValueWord + "|" + prev2AttrValueWord;
     String bigramAttrValueWordSkip31 = prev3AttrValueWord + "|" + prevAttrValueWord;
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWordSkip53_" + bigramAttrValueWordSkip53, 1.0);
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWordSkip42_" + bigramAttrValueWordSkip42, 1.0);
     generalFeatures.put("feature_attrValueWord_bigramAttrValueWordSkip31_" + bigramAttrValueWordSkip31, 1.0);
            
     String trigramAttrValueWord543 = prev5AttrValueWord + "|" + prev4AttrValueWord + "|" + prev3AttrValueWord;
     String trigramAttrValueWord432 = prev4AttrValueWord + "|" + prev3AttrValueWord + "|" + prev2AttrValueWord;
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWord543_" + trigramAttrValueWord543, 1.0);
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWord432_" + trigramAttrValueWord432, 1.0);
            
     String trigramAttrValueWordSkip542 = prev5AttrValueWord + "|" + prev4AttrValueWord + "|" + prev2AttrValueWord;
     String trigramAttrValueWordSkip532 = prev5AttrValueWord + "|" + prev3AttrValueWord + "|" + prev2AttrValueWord;
     String trigramAttrValueWordSkip431 = prev4AttrValueWord + "|" + prev3AttrValueWord + "|" + prevAttrValueWord;
     String trigramAttrValueWordSkip421 = prev4AttrValueWord + "|" + prev2AttrValueWord + "|" + prevAttrValueWord;
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWordSkip542_" + trigramAttrValueWordSkip542, 1.0);
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWordSkip532_" + trigramAttrValueWordSkip532, 1.0);
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWordSkip431_" + trigramAttrValueWordSkip431, 1.0);
     generalFeatures.put("feature_attrValueWord_trigramAttrValueWordSkip421_" + trigramAttrValueWordSkip421, 1.0);*/

    /*
     System.out.println("5AV: " + prev5gramAttrValue);
     System.out.println("5A: " + prev5gramAttr);
     System.out.println("MA: " + mentionedAttrs);
     System.out.println("A_TBM: " + attrsToBeMentioned);
     System.out.println("MAV: " + mentionedAttrValues.subList(0, w));
     System.out.println("AV_TBM: " + attrValuesToBeMentioned);
     System.out.println(costs);
     System.out.println("==============================");*/
    //If arguments have been generated or not
    for (String attr : attrValuesAlreadyMentioned) {
        generalFeatures.put("feature_attr_alreadyMentioned_" + attr, 1.0);
    }
    //If arguments should still be generated or not
    for (String attr : attrsToBeMentioned) {
        generalFeatures.put("feature_attr_toBeMentioned_" + attr, 1.0);
    }

    //Attr specific features (and global features)
    for (String action : availableAttributeActions.get(predicate)) {
        if (action.equals(SFX.TOKEN_END)) {
            if (attrsToBeMentioned.isEmpty()) {
                //valueSpecificFeatures.get(action).put("feature_specific_allAttrValuesMentioned", 1.0);
                valueSpecificFeatures.get(action).put("global_feature_specific_allAttrValuesMentioned", 1.0);
            } else {
                //valueSpecificFeatures.get(action).put("feature_specific_allAttrValuesNotMentioned", 1.0);
                valueSpecificFeatures.get(action).put("global_feature_specific_allAttrValuesNotMentioned", 1.0);
            }
        } else {
            //Is attr in MR?
            if (MR.getAttributes().get(action) != null) {
                //valueSpecificFeatures.get(action).put("feature_specific_isInMR", 1.0);
                //if (!action.equals("empty")
                //        && !action.equals(SFX.TOKEN_END)) {
                valueSpecificFeatures.get(action).put("global_feature_specific_isInMR", 1.0);
                //}
            } else {
                //valueSpecificFeatures.get(action).put("feature_specific_isNotInMR", 1.0);
                //if (!action.equals("empty")
                //        && !action.equals(SFX.TOKEN_END)) {
                valueSpecificFeatures.get(action).put("global_feature_specific_isNotInMR", 1.0);
                //}
            }
            //Is attr already mentioned right before
            if (prevAttr.equals(action)) {
                //valueSpecificFeatures.get(action).put("feature_specific_attrFollowingSameAttr", 1.0);
                valueSpecificFeatures.get(action).put("global_feature_specific_attrFollowingSameAttr", 1.0);
            } else {
                //valueSpecificFeatures.get(action).put("feature_specific_attrNotFollowingSameAttr", 1.0);
                valueSpecificFeatures.get(action).put("global_feature_specific_attrNotFollowingSameAttr", 1.0);
            }
            //Is attr already mentioned
            for (String attrValue : attrValuesAlreadyMentioned) {
                if (attrValue.substring(0, attrValue.indexOf('=')).equals(action)) {
                    //valueSpecificFeatures.get(action).put("feature_specific_attrAlreadyMentioned", 1.0);
                    valueSpecificFeatures.get(action).put("global_feature_specific_attrAlreadyMentioned", 1.0);
                }
            }
            //Is attr to be mentioned (has value to express)
            boolean toBeMentioned = false;
            for (String attrValue : attrValuesToBeMentioned) {
                if (attrValue.substring(0, attrValue.indexOf('=')).equals(action)) {
                    toBeMentioned = true;
                    //valueSpecificFeatures.get(action).put("feature_specific_attrToBeMentioned", 1.0);
                    //if (!action.equals("empty")) {
                    valueSpecificFeatures.get(action).put("global_feature_specific_attrToBeMentioned", 1.0);
                    //}
                }
            }
            if (!toBeMentioned) {
                //valueSpecificFeatures.get(action).put("feature_specific_attrNotToBeMentioned", 1.0);
                //if (!action.equals("empty")) {
                valueSpecificFeatures.get(action).put("global_feature_specific_attrNotToBeMentioned", 1.0);
                //}
            }
        }
        HashSet<String> keys = new HashSet<>(valueSpecificFeatures.get(action).keySet());
        for (String feature1 : keys) {
            for (String feature2 : keys) {
                if (valueSpecificFeatures.get(action).get(feature1) == 1.0
                        && valueSpecificFeatures.get(action).get(feature2) == 1.0
                        && feature1.compareTo(feature2) < 0) {
                    valueSpecificFeatures.get(action).put(feature1 + "&&" + feature2, 1.0);
                }
            }
        }
    }
    return new Instance(generalFeatures, valueSpecificFeatures, costs);
}