text:
package edu.ucsc.dbtune.util;

import java.sql.SQLException;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import edu.ucsc.dbtune.inum.DerbyInterestingOrdersExtractor;
import edu.ucsc.dbtune.inum.FullTableScanIndex;

import edu.ucsc.dbtune.metadata.Catalog;
import edu.ucsc.dbtune.metadata.ColumnOrdering;
import edu.ucsc.dbtune.metadata.Index;
import edu.ucsc.dbtune.metadata.Table;

import edu.ucsc.dbtune.optimizer.plan.InumPlan;
import edu.ucsc.dbtune.optimizer.plan.Operator;
import edu.ucsc.dbtune.optimizer.plan.SQLStatementPlan;
import edu.ucsc.dbtune.optimizer.plan.TableAccessSlot;

import edu.ucsc.dbtune.workload.SQLStatement;

import static com.google.common.collect.Iterables.get;

import static edu.ucsc.dbtune.inum.DerbyInterestingOrdersExtractor.BoundSQLStatementParseTree;
import static edu.ucsc.dbtune.inum.FullTableScanIndex.getFullTableScanIndexInstance;

import static edu.ucsc.dbtune.metadata.ColumnOrdering.ASC;

import static edu.ucsc.dbtune.optimizer.plan.Operator.FETCH;
import static edu.ucsc.dbtune.optimizer.plan.Operator.HJ;
import static edu.ucsc.dbtune.optimizer.plan.Operator.MSJ;
import static edu.ucsc.dbtune.optimizer.plan.Operator.NLJ;
import static edu.ucsc.dbtune.optimizer.plan.Operator.SORT;
import static edu.ucsc.dbtune.optimizer.plan.Operator.SUBQUERY;
import static edu.ucsc.dbtune.optimizer.plan.Operator.TABLE_SCAN;
import static edu.ucsc.dbtune.optimizer.plan.Operator.TEMPORARY_TABLE_SCAN;

import static edu.ucsc.dbtune.util.MetadataUtils.findEquivalentOrCreateNew;
import static edu.ucsc.dbtune.util.MetadataUtils.getIndexesReferencingTables;

/**
 * @author Ivo Jimenez
 */
public final class InumUtils
{
    /**
     * utility class.
     */
    private InumUtils()
    {
    }

    /**
     * Converts the leaf into a table scan, scanning the given table.
     *
     * @param plan
     *      plan on which this operation is executed
     * @param table
     *      table being scanned by the operator
     * @param cost
     *      cost of the operator
     * @throws SQLException
     *      if the plan doesn't have only one leaf
     */
    public static void makeLeafATableScan(SQLStatementPlan plan, Table table, double cost)
        throws SQLException
    {
        if (plan.leafs().size() != 1)
            throw new SQLException("Expecting only one leaf");

        for (Operator o : plan.leafs()) {
            plan.rename(o, TABLE_SCAN);

            if (o.getDatabaseObjects().size() > 0)
                plan.removeDatabaseObject(o);

            plan.assignCost(o, cost);
            plan.assignDatabaseObject(o, table);
            plan.assignColumnsFetched(o, new ColumnOrdering(table.columns().get(0), ASC));
        }
    }

    /**
     * Removes the leafs and subtracts their cost to every node in the remaining plan.
     *
     * @param plan
     *      plan on which this operation is executed
     */
    public static void removeLeafsAndSubstractTheirCost(SQLStatementPlan plan)
    {
        double leafsCost = 0.0;

        for (Operator o : plan.leafs()) {
            leafsCost += o.getAccumulatedCost();
            plan.remove(o);
        }

        for (Operator o : plan.toList())
            plan.assignCost(o, o.getAccumulatedCost() - leafsCost);
    }

    /**
     * Completes a given configuration by adding the FTS index. A complete configuration is
     * guaranteed to have at least one index for every table referenced in the INUM space statement,
     * where the worst case is when the {@link FullTableScanIndex} is the only index for a
     * particular table.
     *
     * @param inumSpace
     *      the set of template plans
     * @param configuration
     *      set of indexes that will be completed by adding FTS for each table referenced by the
     *      inum space
     * @return
     *      a complete configuration
     * @throws SQLException
     *      if {@link #getFullTableScanIndexInstance} throws an exception
     */
    public static Set<Index> complete(Set<InumPlan> inumSpace, Set<? extends Index> configuration)
        throws SQLException
    {
        return complete(get(inumSpace, 0), configuration);
    }

    /**
     * Completes a given configuration by adding the FTS index. A complete configuration is
     * guaranteed to have at least one index for every table referenced in the INUM space statement,
     * where the worst case is when the {@link FullTableScanIndex} is the only index for a
     * particular table.
     *
     * @param plan
     *      a representative plan of the INUM space
     * @param configuration
     *      set of indexes that will be completed by adding FTS for each table referenced by the
     *      inum space
     * @return
     *      a complete configuration
     * @throws SQLException
     *      if {@link #getFullTableScanIndexInstance} throws an exception
     */
    public static Set<Index> complete(SQLStatementPlan plan, Set<? extends Index> configuration)
        throws SQLException
    {
        Set<Index> indexes = getIndexesReferencingTables(configuration, plan.getTables());

        for (Table table : plan.getTables())
            indexes.add(FullTableScanIndex.getFullTableScanIndexInstance(table));

        return indexes;
    }

    /**
     * Returns the covering atomic configuration for the given plan. A covering index for a table
     * referenced in a statement covers all the columns accessed by it. Thus, the covering atomic
     * configuration is the set of covering indexes for a statement.
     *
     * @param plan
     *      the plan returned by an optimizer
     * @return
     *      the minimum atomic configuration for the statement associated with the plan
     * @throws SQLException
     *      if there's a table without a corresponding slot in the given inum plan
     */
    public static Set<Index> getCoveringAtomicConfiguration(InumPlan plan) throws SQLException
    {
        Set<Index> min = new HashSet<Index>();

        for (Table t : plan.getTables())
            if (plan.getSlot(t) == null)
                throw new SQLException("No slot for " + t + " in " + plan);
            else
                min.add(getCoveringIndex(plan.getSlot(t)));

        return min;
    }

    /**
     * @param slot
     *      slot for which a covering index is created
     * @return
     *      the index that covers the columns accessed by the slot
     * @throws SQLException
     *      if the FTS for the slot doesn't exist
     */
    public static Index getCoveringIndex(TableAccessSlot slot) throws SQLException
    {
        if (slot.getColumnsFetched() == null)
            throw new SQLException("Can't find columns fetched for " + slot.getTable());

        if (slot.getColumnsFetched().size() == 0)
            return getFullTableScanIndexInstance(slot.getTable());

        return findEquivalentOrCreateNew(slot.getColumnsFetched());
    }

    /**
     * Returns the maximum atomic configuration for the statement. The maximum configuration is the
     * set of indexes that contain no attributes other than the join columns used on the statement.
     *
     * @param statement
     *      SQL statement for which the INUM space is computed
     * @param catalog
     *      used to retrieve metadata for objects referenced in the statement
     * @return
     *      the maximum atomic configuration for the statement associated with the plan
     * @throws SQLException
     *      if there's a table without a corresponding slot in the given inum plan
     */
    public static Set<Index> getMaximumAtomicConfiguration(
            SQLStatement statement, Catalog catalog)
        throws SQLException
    {
        Set<ColumnOrdering> ios = extractInterestingOrdersFromJoinPredicates(statement, catalog);
        Set<Index> max = new HashSet<Index>();

        for (ColumnOrdering i : ios)
            max.add(findEquivalentOrCreateNew(i));

        return max;
    }

    /**
     * Extracts interesting orders through the use of the {@link DerbyInterestingOrdersExtractor}.
     *
     * @param statement
     *      SQL statement for which the INUM space is computed
     * @param catalog
     *      used to retrieve metadata for objects referenced in the statement
     * @return
     *      the maximum atomic configuration for the statement associated with the plan
     * @throws SQLException
     *      if there's a table without a corresponding slot in the given inum plan
     */
    public static Set<ColumnOrdering> extractInterestingOrders(
            SQLStatement statement, Catalog catalog)
        throws SQLException
    {
        return new DerbyInterestingOrdersExtractor(catalog).extract(statement);
    }

    /**
     * Extracts interesting orders through the use of the {@link DerbyInterestingOrdersExtractor}.
     *
     * @param statement
     *      SQL statement for which the INUM space is computed
     * @param catalog
     *      used to retrieve metadata for objects referenced in the statement
     * @return
     *      the maximum atomic configuration for the statement associated with the plan
     * @throws SQLException
     *      if there's a table without a corresponding slot in the given inum plan
     */
    public static Set<ColumnOrdering> extractInterestingOrdersFromJoinPredicates(
            SQLStatement statement, Catalog catalog)
        throws SQLException
    {
        DerbyInterestingOrdersExtractor ioExtractor;
        BoundSQLStatementParseTree parseTree;

        ioExtractor = new DerbyInterestingOrdersExtractor(catalog);
        parseTree = new BoundSQLStatementParseTree(ioExtractor.getParseTree(statement), catalog);

        Set<ColumnOrdering> ios = new HashSet<ColumnOrdering>();

        ioExtractor.extractFromJoinPredicates(parseTree, ios);

        for (BoundSQLStatementParseTree subquery : parseTree.getBoundSubqueries())
            ioExtractor.extractFromJoinPredicates(subquery, ios);

        return ios;
    }

    /**
     * Extracts the list of tables referenced by a statement by parsing the SQL text.
     *
     * @param statement
     *      SQL statement being parsed in order to extract table references
     * @param catalog
     *      used to retrieve metadata for objects referenced in the statement
     * @return
     *      the tables referenced in the statement
     * @throws SQLException
     *      if there's a problem while parsing the SQL text
     */
    public static List
 extractTablesReferencedByStatement(
            SQLStatement statement, Catalog catalog)
        throws SQLException
    {
        List
 tables = new ArrayList
();
        DerbyInterestingOrdersExtractor ioExtractor;
        BoundSQLStatementParseTree parseTree;

        ioExtractor = new DerbyInterestingOrdersExtractor(catalog);
        parseTree = new BoundSQLStatementParseTree(ioExtractor.getParseTree(statement), catalog);

        for (Table t : parseTree.getTables())
            tables.add(t);

        return tables;
    }

    /**
     * Renames the first occurrence of a {@link TEMPORARY_TABLE_SCAN} leaf operator (to {@link
     * SORT}) by calling {@link #renameClosestJoinAndRemoveBranchComingFrom}.
     *
     * @param plan
     *      plan whose non-leaf table scan operators are to be converted into leafs
     * @return
     *      {@code true} if a rename was performed; {@code false} otherwise
     * @throws SQLException
     *      if {@link #renameClosestJoinAndRemoveBranchComingFrom} throws an exception
     */
    public static boolean removeTemporaryTables(SQLStatementPlan plan) throws SQLException
    {
        for (Operator o : plan.leafs()) {
            if (!o.getName().equals(TEMPORARY_TABLE_SCAN))
                continue;

            if (plan.contains(MSJ) || plan.contains(HJ) || plan.contains(NLJ))
                renameClosestJoinAndRemoveBranchComingFrom(plan, o, SORT);
            else
                plan.remove(o);

            return true;
        }

        return false;
    }

    /**
     * Renames the closest node in the three (bottom-up) that is an ascendant of {@code operator}
     * and removes the entire branch that hangs from it (from the point of view of {@code
     * operator}). For example, if a plan like the following is given:
     *

     * {@code .
     *
     *                 Rows
     *                RETURN
     *                (   1)
     *                 Cost
     *                  I/O
     *                  |
     *                2824.22
     *                NLJOIN
     *                (   2)
     *                211540
     *                207998
     *             /----+----\
     *         9320.87        0.303
     *         TBSCAN        TBSCAN
     *         (   3)        (   4)
     *         211526       0.0103428
     *         207998           0
     *           |             |
     *       6.00122e+06        2
     *     TABLE: TPCH       SORT
     *        LINEITEM       (   5)
     *           Q3         0.0030171
     *                          0
     *                         |
     *                          2
     *                  TEMPORARY_TABLE_SCAN
     *                       (   6)
     *                     2.95215e-05
     *                          0
     *                         |
     *                          2
     * }
     *

     *

     * If this method is invoked with {@code plan, genRowOperator, "NLJOIN", "SORT"}, the plan looks
     * like the following when this method returns:
     *

     * {@code .
     *
     *                 Rows
     *                RETURN
     *                (   1)
     *                 Cost
     *                  I/O
     *                  |
     *                2824.22
     *                 SORT
     *                (   2)
     *                211540
     *                207998
     *                  |
     *                9320.87
     *                TBSCAN
     *                (   3)
     *                211526
     *                207998
     *                  |
     *              6.00122e+06
     *            TABLE: TPCH
     *               LINEITEM
     *                  Q3
     * }
     *

     *
     * @param plan
     *      plan that is modified
     * @param child
     *      node whose closest parent named {@code oldName} gets renamed. The branch that comes from
     *      this node up to the parent is entirely removed
     * @param newName
     *      new name of the parent
     * @throws SQLException
     *      if a {@code operatorName} is not found in any ascendant of {@code child}
     */
    private static void renameClosestJoinAndRemoveBranchComingFrom(
            SQLStatementPlan plan, Operator child, String newName)
        throws SQLException
    {
        Operator ascendant = null;
        Operator shild = child;

        while ((ascendant = plan.getParent(shild)) != null) {

            if (ascendant.isJoin())
                break;

            shild = ascendant;
        }

        if (ascendant == null)
            throw new SQLException(
                "In\n" + plan + "\n\nCan't find closest join (ascendant) of " + child);

        plan.rename(ascendant, newName);
        plan.remove(shild);
    }

    /**
     * In some cases a plan might have a base-table access operator ({@link INDEX_SCAN} or {@link
     * TABLE_SCAN}) that is not a leaf. For example, in DB2, the following query (TPC-H, query 16):
     *

     *

     * {@code .
     *
     * select
     *     p_brand,
     *     p_type,
     *     p_size,
     *     count(distinct ps_suppkey) as supplier_cnt
     * from
     *     tpch.partsupp,
     *     tpch.part
     * where
     *     p_partkey = ps_partkey
     *     and p_brand <> 'Brand#41'
     *     and p_type not like 'MEDIUM BURNISHED%'
     *     and p_size in (4, 21, 15, 41, 49, 43, 27, 47)
     *     and ps_suppkey not in (
     *         select
     *             s_suppkey
     *         from
     *             tpch.supplier
     *         where
     *             s_comment like '%Customer%Complaints%'
     *     )
     * group by
     *     p_brand,
     *     p_type,
     *     p_size
     * order by
     *     supplier_cnt desc,
     *     p_brand,
     *     p_type,
     *     p_size;
     *
     *
     * }
     *

     *

     * Generates the following plan:
     *

     *

     * {@code .
     *
     *                       HSJOIN
     *                       (   7)
     *                      1.193e+06
     *                        41538
     *               /---------+---------\
     *           400000                  30506.7
     *           TBSCAN                  TBSCAN
     *           (   8)                  (  12)
     *         1.17329e+06               7750.16
     *            32343                   7617
     *         /---+----\                  |
     *     599.479      800000           200000
     *     TBSCAN   TABLE: TPCH      TABLE: TPCH
     *     (   9)      PARTSUPP           PART
     *     419.594        Q6               Q5
     *       410
     *       |
     *     599.479
     *     SORT
     *     (  10)
     *     419.564
     *       410
     *       |
     *     599.479
     *     TBSCAN
     *     (  11)
     *     419.373
     *       410
     *       |
     *      10000
     * TABLE: TPCH
     *    SUPPLIER
     *       Q3
     * }
     *

     *

     * The {@code TBSCAN} (id=8) operator represents the subquery that is applied to the
     * {@code SUPPLIER} relation, for each distinct value of {@code ps_suppkey}.
     *

     * This method renames the non-leaf node to {@link #SUBQUERY} and creates a new leaf node that
     * corresponds to the scan of the table. The {@link #SUBQUERY} operator can be thought as a kind
     * of single-scan , i.e. both children of {@code SUBQUERY} are scanned once.
     *

     * {@code .
     *
     *                       HSJOIN
     *                       (   7)
     *                      1.193e+06
     *                        41538
     *               /---------+---------\
     *           400000                  30506.7
     *           SUBQUERY                TBSCAN
     *           (   8)                  (  12)
     *         1.17329e+06               7750.16
     *            32343                   7617
     *         /---+----\                  |
     *     599.479     400000             200000
     *     TBSCAN      TBSCAN         TABLE: TPCH
     *     (   9)      (   13)              PART
     *     419.594   1.17329e+06            Q5
     *       410        32343
     *       |            |
     *     599.47      800000
     *     SORT      TABLE: TPCH
     *     (  10)     PARTSUPP
     *     419.564       Q6
     *       410
     *       |
     *     599.479
     *     TBSCAN
     *     (  11)
     *     419.373
     *       410
     *       |
     *      10000
     * TABLE: TPCH
     *    SUPPLIER
     *       Q3
     * }
     *

     *

     * This method operates in a bottom up approach and returns immediately after it performs the
     * first rewrite. This with the purpose of avoiding concurrent modification of the members of
     * the plan
     *
     * @param plan
     *      plan whose non-leaf table access operators are to be converted into leafs
     * @return
     *      {@code true} if the plan was modified; {@code false} otherwise
     * @throws SQLException
     *      if an non-leaf data access operator has more than one children
     */
    public static boolean rewriteNonLeafDataAccessOperators(SQLStatementPlan plan)
        throws SQLException
    {
        for (Operator o : plan.leafs()) {

            Operator parent;
            Operator child = o;

            while ((parent = plan.getParent(child)) != null) {

                if (child.isDataAccess() && !child.equals(FETCH)) {

                    Operator newSibling;
                    Operator leaf;
                    double leafCost;

                    if (plan.getChildren(child).size() == 1) {

                        newSibling = plan.getChildren(child).get(0);

                        leafCost = child.getAccumulatedCost() - newSibling.getAccumulatedCost();

                        leaf = new Operator(child.getName(), leafCost, child.getCardinality());

                        leaf.add(child.getDatabaseObjects().get(0));
                        leaf.addColumnsFetched(child.getColumnsFetched());
                        leaf.add(child.getPredicates());

                        plan.rename(child, SUBQUERY);
                        plan.removeDatabaseObject(child);
                        plan.removeColumnsFetched(child);
                        plan.removePredicates(child);
                        plan.setChild(child, leaf);

                        return true;
                    } else if (plan.getChildren(child).size() > 1) {
                        throw new SQLException(
                            "Don't know how to handle " + TABLE_SCAN + " with more than one child");
                    }
                    // else {} // is fine, it is an actual leaf
                }

                child = parent;
            }

        }

        return false;
    }
}


text:
package com.blogspot.oraclestack.eventhandlers;

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.HashMap;
import oracle.core.ojdl.logging.ODLLevel;
import oracle.core.ojdl.logging.ODLLogger;
import oracle.iam.identity.exception.NoSuchUserException;
import oracle.iam.identity.exception.SearchKeyNotUniqueException;
import oracle.iam.identity.exception.UserModifyException;
import oracle.iam.identity.exception.ValidationFailedException;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.api.UserManagerConstants;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.identity.usermgmt.vo.UserManagerResult;
import oracle.iam.identity.vo.Identity;
import oracle.iam.platform.Platform;
import oracle.iam.platform.authz.exception.AccessDeniedException;
import oracle.iam.platform.kernel.EventFailedException;
import oracle.iam.platform.kernel.spi.PreProcessHandler;
import oracle.iam.platform.kernel.vo.AbstractGenericOrchestration;
import oracle.iam.platform.kernel.vo.BulkEventResult;
import oracle.iam.platform.kernel.vo.BulkOrchestration;
import oracle.iam.platform.kernel.vo.EventResult;
import oracle.iam.platform.kernel.vo.Orchestration;

/**
 * Demonstrates implementing single and bulk execute method for a preprocess
 * event handler on user lock operation. This can also be used as a template for
 * implementing other preprocess event handlers. Place additional implementations/logic
 * in the executeEvent() method since both execute() methods make calls to it.
 *
 * Note: For bulk lock operation, modifying the parameters applies to all users
 * in the orchestration. When using this preprocess event handler on DISABLE and
 * ENABLE operations, modifying the orchestration parameters do nothing.
 *
 * @author rayedchan
 */
public class UserLockPreprocessEH implements PreProcessHandler
{
    // Logger
    private static final ODLLogger LOGGER = ODLLogger.getODLLogger(UserLockPreprocessEH.class.getName());

    // OIM API Services
    private static final UserManager USR_MGR = Platform.getServiceForEventHandlers(UserManager.class, null, "ADMIN","UserLockPreprocessEH", null);

    /**
     * Executes the event handler on a single event operation.
     * @param processId Process Id
     * @param eventId   Event Id
     * @param orchestration Orchestration contains target user information
     * @return new event result
     */
    @Override
    public EventResult execute(long processId, long eventId, Orchestration orchestration)
    {
        LOGGER.log(ODLLevel.NOTIFICATION, "Enter execute method: Process Id = {0}, Event Id = {1}", new Object[]{processId, eventId});

        // Get USR_KEY of target user from orchestration
        String userKey = orchestration.getTarget().getEntityId();
        LOGGER.log(ODLLevel.NOTIFICATION, "User Key: {0}", new Object[]{userKey});

        // Get Interevent data; only current User state avaliable
        HashMap<String,Serializable> interEventMap = orchestration.getInterEventData();
        LOGGER.log(ODLLevel.TRACE, "InterEvent Data: {0}", new Object[]{interEventMap});

        // Get the modified parameters upon lock operation
        HashMap<String,Serializable> modParams = orchestration.getParameters();
        LOGGER.log(ODLLevel.TRACE, "Modified Paramerters: {0}", new Object[]{modParams});

        // Get current user state
        User user = (User) interEventMap.get("CURRENT_USER");
        LOGGER.log(ODLLevel.TRACE, "Current User: {0}", new Object[]{user});

        // Get user login
        String userLogin = user.getLogin();
        LOGGER.log(ODLLevel.NOTIFICATION, "User Login: {0}", new Object[]{userLogin});

        try
        {
            // Modify the orchestration parameters for the target user
            this.updateOrchParams(modParams);
            LOGGER.log(ODLLevel.TRACE, "New Modified Parameters: {0}", new Object[]{modParams});

            // Apply additional modification to user.
            // NOTE: These modification can also be changed in the orchestration.
            this.executeEvent(user);
        }

        catch (Exception e)
        {
            LOGGER.log(ODLLevel.SEVERE, MessageFormat.format("Failed for {0}", new Object[]{userLogin}), e);
            throw new EventFailedException(processId,"","","","", new Exception(e.getMessage()));
        }

        LOGGER.log(ODLLevel.NOTIFICATION, "End execute method.");
        return new EventResult();
    }

    /**
     * Executes the event handler on bulk event operation.
     * @param processId Process Id
     * @param eventId   Event Id
     * @param bulkOrchestration Bulk Orchestration contains target users information
     * @return A new BulkEventResult
     */
    @Override
    public BulkEventResult execute(long processId, long eventId, BulkOrchestration bulkOrchestration)
    {
        LOGGER.log(ODLLevel.NOTIFICATION, "Enter bulk execute method: Process Id = {0}, Event Id = {1}", new Object[]{processId, eventId});

        // Get the user keys from the orchestration
        String[] entityIds = bulkOrchestration.getTarget().getAllEntityId();

        // Get changes for all users
        HashMap<String, Serializable>[] bulkParameters = bulkOrchestration.getBulkParameters();
        int numEvents = bulkParameters.length;
        LOGGER.log(ODLLevel.NOTIFICATION, "Number of Bulk Parameters: {0}", new Object[]{numEvents});

        // Modifying the orchestration parameters applies to all users
        if(numEvents > 0)
        {
            // Get the modified parameters; Shared among the users
            HashMap<String, Serializable> modParams = bulkParameters[0];
            LOGGER.log(ODLLevel.TRACE, "Modified Parameters: {0}", new Object[]{modParams});

            // Call method to modify the orchestration parameters
            this.updateOrchParams(modParams);
            LOGGER.log(ODLLevel.TRACE, "New Modified Parameters: {0}", new Object[]{modParams});
        }

        // Get interEventData
        HashMap<String, Serializable> interEventData = bulkOrchestration.getInterEventData();

        // Get list of users
        Object curUsersObj = interEventData.get("CURRENT_USER");
        Identity[] users  = (Identity[]) curUsersObj;
        int numUsers = users.length;
        LOGGER.log(ODLLevel.NOTIFICATION, "Number of users to process: {0}", new Object[]{numUsers});

        // Iterate each user; apply changes to each user
        for(int i = 0; i < numUsers; i++)
        {
            // Get current user state
            User user = (User) users[i];
            LOGGER.log(ODLLevel.TRACE, "User: {0}", new Object[]{user});

            // Get USR_KEY of current user being modified
            String userKey = entityIds[i];
            LOGGER.log(ODLLevel.NOTIFICATION, "OIM User Key: {0}", new Object[]{userKey});

            // Get user login
            String userLogin = user.getLogin();
            LOGGER.log(ODLLevel.NOTIFICATION, "User Login: {0}", new Object[]{userLogin});

            try
            {
                // Modify the user attributes
                this.executeEvent(user);
            }

            catch (Exception e)
            {
                LOGGER.log(ODLLevel.SEVERE, MessageFormat.format("Failed for {0}", new Object[]{userLogin}), e);
            }
        }

        LOGGER.log(ODLLevel.INFO, "End bulk execute.");
        return new BulkEventResult();
    }

    /**
     * Used to modify the orchestration parameters. This can be called in
     * the single and bulk execute. For bulk lock operation, modifying the
     * orchestration parameters applies to all users given in the orchestration.
     * @param user  OIM User
     * @param orchParams   Orchestration parameters to add, remove, or update user attributes
     */
    private void updateOrchParams(HashMap<String,Serializable> orchParams)
    {
        // Modify orchestration parameters so OIM can propagate changes to downstream processes (E.g. Postprocess event handler, Process Tasks)
        // TODO: Apply your changes here.
        orchParams.put(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId(), "LOCKED"); // Department Number
        orchParams.put(UserManagerConstants.AttributeName.TITLE.getId(), "LOCKED"); // Title
        orchParams.put(UserManagerConstants.AttributeName.EMPLOYEE_NUMBER.getId(), "LOCKED"); // Employee Number
    }

    /**
     * Used if different attribute values are to be applied for each user. This can be called in
     * the single and bulk execute since this method processes one user at a time.
     * @param user  OIM User
     */
    private void executeEvent(User user) throws ValidationFailedException, AccessDeniedException, UserModifyException, NoSuchUserException, SearchKeyNotUniqueException
    {
        String userLogin = user.getLogin();
        LOGGER.log(ODLLevel.NOTIFICATION, "Preparing updates for {0}", new Object[]{userLogin});
        HashMap<String,Object> attrs = new HashMap<String,Object>();

        // Update user via API
        // TODO: Apply your changes here.
        attrs.put(UserManagerConstants.AttributeName.STREET.getId(), "LOCKED: " + user.getLogin());
        attrs.put(UserManagerConstants.AttributeName.POSTAL_ADDRESS.getId(), "LOCKED: " + user.getId());
        User modUser = new User(userLogin, attrs);
        UserManagerResult result = USR_MGR.modify("User Login", userLogin, modUser);

        LOGGER.log(ODLLevel.NOTIFICATION, "Entity ID: {0}", new Object[]{result.getEntityId()});
        LOGGER.log(ODLLevel.NOTIFICATION, "Failed Results: {0}", new Object[]{result.getFailedResults()});
        LOGGER.log(ODLLevel.NOTIFICATION, "Status: {0}", new Object[]{result.getStatus()});
        LOGGER.log(ODLLevel.NOTIFICATION, "Succeeded Results: {0}", new Object[]{result.getSucceededResults()});
        LOGGER.log(ODLLevel.NOTIFICATION, "Updated {0} with {1}", new Object[]{userLogin, attrs});
    }

    @Override
    public void initialize(HashMap<String, String> arg0)
    {
    }

    @Override
    public boolean cancel(long processId, long eventId, AbstractGenericOrchestration orchestration)
    {
        return false;
    }

    @Override
    public void compensate(long processId, long eventId, AbstractGenericOrchestration orchestration)
    {
    }
}

redpajama_set_name: RedPajamaGithub


text:
#region License
// HelpCommandLineOption.cs
// Copyright (c) 2013, Simon Williams
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provide
// d that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
// the following disclaimer in the documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;

namespace Fclp.Internals
{
	/// <summary>
	/// Represents a command line option that determines whether to show the help text.
	/// </summary>
	public class HelpCommandLineOption : IHelpCommandLineOptionResult
	{
		ICommandLineOptionFormatter _optionFormatter;

		/// <summary>
		/// Initialises a new instance of <see cref="HelpCommandLineOption"/> class.
		/// </summary>
		/// <param name="helpArgs">The registered help arguments.</param>
		public HelpCommandLineOption(IEnumerable<string> helpArgs)
		{
			HelpArgs = helpArgs ?? new List<string>();
		}

		/// <summary>
		/// Gets the registered help arguments.
		/// </summary>
		public IEnumerable<string> HelpArgs { get; private set; }

		/// <summary>
		/// Gets or sets the callback method.
		/// </summary>
		internal Action<string> ReturnCallback { get; set; }

		private Action ReturnCallbackWithoutParser { get; set; }

		private bool ShouldUseForEmptyArgs { get; set; }

		/// <summary>
		/// Gets or sets any header to display at the top of the printed options.
		/// </summary>
		public string Header { get; set; }

		/// <summary>
		/// Gets or sets the <see cref="ICommandLineOptionFormatter"/> to use to format the options.
		/// </summary>
		public ICommandLineOptionFormatter OptionFormatter
		{
			get { return _optionFormatter ?? (_optionFormatter = new CommandLineOptionFormatter { Header = this.Header }); }
			set { _optionFormatter = value; }
		}

		/// <summary>
		/// Specifies the method to invoke with the formatted command line options when any of the setup
		/// help arguments are found. If a callback is not required either do not call it, or specify <c>null</c>.
		/// </summary>
		/// <param name="callback">
		/// The callback to execute with the formatted command line options.
		/// </param>
		/// <returns>A <see cref="ICommandLineOptionFluent{T}"/>.</returns>
		public IHelpCommandLineOptionFluent Callback(Action<string> callback)
		{
			ReturnCallback = callback;
			return this;
		}

		/// <summary>
		/// Specified the method to invoke when any of the setup help arguments are found. If a callback is not required
		/// either do not call it, or specified <c>null</c>.
		/// </summary>
		/// <param name="callback">
		/// The callback to execute. If you have also setup the other help callback this will be called last.
		/// </param>
		/// <returns>A <see cref="ICommandLineOptionFluent{T}"/>.</returns>
		public IHelpCommandLineOptionFluent Callback(Action callback)
		{
			ReturnCallbackWithoutParser = callback;
			return this;
		}

		/// <summary>
		/// Registers a custom <see cref="ICommandLineOptionFormatter"/> to use to generate the help text.
		/// </summary>
		/// <param name="formatter">The custom formatter to use. This must not be <c>null</c>.</param>
		public IHelpCommandLineOptionFluent WithCustomFormatter(ICommandLineOptionFormatter formatter)
		{
			this.OptionFormatter = formatter;
			return this;
		}

		/// <summary>
		/// Provides a custom header to be printed before the registered options.
		/// </summary>
		/// <param name="header">The header to use.</param>
		public IHelpCommandLineOptionFluent WithHeader(string header)
		{
			this.Header = header;
			return this;
		}

		/// <summary>
		/// Specifies that if empty arguments are found then the behaviour should be the same as when any help arguments
		/// are found.
		/// </summary>
		/// <returns>A <see cref="IHelpCommandLineOptionFluent"/>.</returns>
		public IHelpCommandLineOptionFluent UseForEmptyArgs()
		{
			this.ShouldUseForEmptyArgs = true;
			return this;
		}

		/// <summary>
		/// Determines whether the help text should be shown.
		/// </summary>
		/// <param name="parsedOptions">The parsed command line arguments</param>
		/// <param name="comparisonType">The type of comparison to use when comparing Option names.</param>
		/// <returns>
		/// true if the parser operation should cease and <see cref="ShowHelp" /> should be called; otherwise false if the parse operation to continue.
		/// </returns>
		public bool ShouldShowHelp(IEnumerable<ParsedOption> parsedOptions, StringComparison comparisonType)
		{
			var parsed = parsedOptions != null ? parsedOptions.ToList() : new List<ParsedOption>();

			if (parsed.Any() == false && ShouldUseForEmptyArgs)
			{
				return true;
			}

			return this.HelpArgs.Any(helpArg => parsed.Any(cmdArg => helpArg.Equals(cmdArg.Key, comparisonType)));
		}

		/// <summary>
		/// Shows the help text for the specified registered options.
		/// </summary>
		/// <param name="options">The options to generate the help text for.</param>
		public void ShowHelp(IEnumerable<ICommandLineOption> options)
		{
			if (ReturnCallback != null)
			{
				var formattedOutput = this.OptionFormatter.Format(options);
				this.ReturnCallback(formattedOutput);
			}

			if (ReturnCallbackWithoutParser != null)
			{
				this.ReturnCallbackWithoutParser();
			}
		}
	}
}


text:
.class public LTestCase;

.super Ljava/lang/Object;

.method private static flagToString(I)Ljava/lang/String;
  .registers 2

    # The bug is triggered when inlining a method with few Load/StoreLocals but
    # many constants. The switch instruction helps with that.

    sparse-switch p0, :sswitch_data_1a
    const/4 v0, 0x0

    :goto_4
    return-object v0

  :sswitch_5
    const-string v0, "DEFAULT"
    goto :goto_4

  :sswitch_8
    const-string v0, "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS"
    goto :goto_4

  :sswitch_b
    const-string v0, "FLAG_REQUEST_TOUCH_EXPLORATION_MODE"
    goto :goto_4

  :sswitch_e
    const-string v0, "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY"
    goto :goto_4

  :sswitch_11
    const-string v0, "FLAG_REPORT_VIEW_IDS"
    goto :goto_4

  :sswitch_14
    const-string v0, "FLAG_REQUEST_FILTER_KEY_EVENTS"
    goto :goto_4

  :sswitch_17
    const-string v0, "FLAG_RETRIEVE_INTERACTIVE_WINDOWS"
    goto :goto_4

  :sswitch_data_1a
  .sparse-switch
      0x1 -> :sswitch_5
      0x2 -> :sswitch_8
      0x4 -> :sswitch_b
      0x8 -> :sswitch_e
      0x10 -> :sswitch_11
      0x20 -> :sswitch_14
      0x40 -> :sswitch_17
  .end sparse-switch
.end method

.method public static testCase(I)Ljava/lang/String;
  .registers 2
    invoke-static {v1}, LTestCase;->flagToString(I)Ljava/lang/String;
    move-result-object v0
    return-object v0
.end method


text:
package ar.edu.utn.frro.web.rest.errors;

public final class ErrorConstants {

    public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure";
    public static final String ERR_ACCESS_DENIED = "error.accessDenied";
    public static final String ERR_VALIDATION = "error.validation";
    public static final String ERR_METHOD_NOT_SUPPORTED = "error.methodNotSupported";

    private ErrorConstants() {
    }

}


text:
n = int(input())
arr = map(int , input().split())
print(sum(arr))


text:
default: lint

lint: node_modules/.bin/jslint
	@$< src/scripts/*.js src/scripts/content/*.js

node_modules/.bin/jslint:
	npm install

dist: clean
	@if [ ! -d "out" ]; then mkdir -p out; fi
	@cp -R src/manifest.json src/images src/scripts src/styles src/html src/sounds out/
	@cd out && find . -path '*/.*' -prune -o -type f -print | zip ../ch_toggl-button.zip -@
	@rm -rf out

clean:
	@if [ -f "ch_toggl-button.zip" ]; then rm ch_toggl-button.zip; fi
	@if [ -f "ff_toggl-button.zip" ]; then rm ff_toggl-button.zip; fi

authors:
	#git log --format='%aN <%aE>' | awk '{arr[$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn | cut -d\  -f2- > AUTHORS
	@echo "Seems to not work for some reason. Copy manually the command from Makefile"

ff-dist: clean
	@if [ ! -d "out" ]; then mkdir -p out; fi
	@cp src/manifest_ff.json src/manifest.json
	@cp -R src/manifest.json src/images src/scripts src/styles src/html src/sounds out/
	@cd out && find . -path '*/.*' -prune -o -type f -print | zip ../ff_toggl-button.zip -@
	@rm -rf out
	@git checkout .


text:
package com.example.administrator.qiongyou.model.I.Impl;

import com.example.administrator.qiongyou.bean.Recommend;
import com.example.administrator.qiongyou.model.I.RecommendModelInterf;
import com.example.administrator.qiongyou.presenter.I.RecommendPresenterIn;
import com.example.administrator.qiongyou.util.ApiManager;

import java.util.HashMap;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by Administrator on 2017/3/5.
 */

public class RecommendModel implements RecommendModelInterf {

    private RecommendPresenterIn recommendPresenterIn;

    public RecommendModel(RecommendPresenterIn recommendPresenterIn) {
        this.recommendPresenterIn = recommendPresenterIn;
    }

    @Override
    public void requestData(HashMap<String, String> hashMap) {

        ApiManager.getInstence().getService()
                .getRecommend(hashMap)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Recommend>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Recommend value) {
                        requestSuccess(value);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    @Override
    public void requestSuccess(Recommend recommend) {
        recommendPresenterIn.onRequestSuccess(recommend);
    }

    @Override
    public void requestFailed() {
        recommendPresenterIn.onRequestFailed();
    }

    @Override
    public void requestCompleted() {

    }
}


text:
$(document).ready(function(){
    if($("#records tbody tr").length > 0){
        $("#records").treeTable({treeColumn: 1, clickableNodeNames: true, indent: 25});
    }

    $("#records").find('input[type="checkbox"]').live('click', function(){
        nodeId = $(this).parents('tr').attr('id');
        thisIsChecked = $(this).attr('checked');

        childNodes = $("#records").find('tr[class^="child-of-' + nodeId + '"]');
        $(childNodes).each(function(){
            if(thisIsChecked == 'checked'){
                $(this).find('input[type="checkbox"]').attr('checked', 'checked');
            }else{
                $(this).find('input[type="checkbox"]').removeAttr('checked');
            }
        })
    });

    $('.category-edit-trigger').click(function(){
        categoryManagement(this, false);
    });

    $('.category-add-trigger').click(function(){
        categoryManagement(this, true);
    });

    $('.category-delete-trigger').click(function(){
        categoryDelete(this);
    });
});

categoryManagement = function(node, isNew){
    $("#modalCategory").modal().css({
            "width": function () {
                return ($(document).width() * .5) + "px";
            },
            "margin-left": function () {
                return -($(this).width() / 2);
    }});

    $("#modalCategory").find('input').val('');

    if(isNew == false){
        $("#modalCategory").find('#category-name').val($(node).attr('data-category-name'));
        $("#modalCategory").find('#category-parent-id').val($(node).attr('data-category-parent-id'));
        $("#modalCategory").find('#category-id').val($(node).attr('data-category-id'));
    }else{
        if($(node).attr('data-category-parent-id')){
            $("#modalCategory").find('#category-parent-id').val($(node).attr('data-category-parent-id'));
        }
    }

    $('#addBtn').unbind('click');

    $('#addBtn').click(function(){
        $('#addBtn').attr('disabled', 'disabled');

        postData = {
            name : $("#modalCategory").find('#category-name').val(),
            parent_id : $("#modalCategory").find('#category-parent-id').val(),
        }

        if(isNew == false){
            postData.id = $("#modalCategory").find('#category-id').val();
        }

        $.ajax({
            url             : "/ui/categories/form-post",
            type            : 'post',
            data            : postData,
            dataType        : 'json',
            success         : function(a){
                if(a.success == '1'){
                   document.location.reload();
                }else{
                    _alert({
                        type: 'error',
                        title: 'Error',
                        text: a.msg
                    });
                }
            }
        });
    });
}

$('#buscaCategorias').typeahead({
    updater : function(a,b){
        $('tr[data-description="' + a + '"]').reveal();
    },
    source : categoriesName
});

$('#selectAll').click(function(e){
    $("#records").find('tbody').find('tr').expand();
    $("#records").find('tbody').find('tr:last').reveal();
});

categoryDelete = function(node){
    confirmOptions = {
        title: app_messages['confirm_single_delete_title'],
        text: app_messages['confirm_category_deleting'],
        ok: app_messages['remove'],
        cancel: app_messages['cancel']
    };

    isChild = false;
    parentNodeId = '';

    console.log(node);

    if($(node).hasClass('category-delete-trigger-all') == false){
        _tr = $(node).parents('tr');
        _tbody = $(_tr).parents('tbody');

        subcategories = $(_tbody).find('tr[class^="child-of-' + $(_tr).attr('id') + '"]');

        if($(subcategories).length > 0){
            confirmOptions.text = app_messages['confirm_category_with_sub_deleting'];
        }

        elementCssClass = $(_tr).attr('class').split(' ');

        $(elementCssClass).each(function(a, b){
            if(b.indexOf('child-of-') != -1){
                isChild = true;
                parentNodeId = b.substring(9+(b.indexOf('child-of-')), b.length);
            }
        });

        idToDelete = $(node).attr('data-category-id');
    }else{
        isChild = false;

        toDeleteCollection = new Array();

        $('.cboxSelectRow:checked').each(function(){
            toDeleteCollection[toDeleteCollection.length] = $(this).val();
        });

        idToDelete = toDeleteCollection.join(',');
    }

    _confirm(
        confirmOptions
    ).done(function() {
        _wait({
            'text': app_messages['loading_content']
        });

        $.ajax({
            url: '/ui/categories/delete',
            data : {id:idToDelete},
            type: 'post',
            dataType: 'json',
            success: function(a) {
                if (a.success == '1') {
                    window.location.reload();
                } else {
                    _alert({
                        type: 'error',
                        title: 'Error',
                        text: a.msg
                    });

                    _wait.stop();
                }
            }
        });
    }).fail(function() {
        // your optional alert code
    });
};


text:
package org.apache.poi.ss.formula.functions;

import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.*;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Implementation for Excel IMAGINARY() function.

 *

 * Syntax:
 IMAGINARY  (Inumber)

 *

 * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format.
 *

 * Inumber     is a complex number for which you want the imaginary coefficient.
 *

 * Remarks
 *

 *
Use COMPLEX to convert real and imaginary coefficients into a complex number.

 *

 *
 * @author cedric dot walter @ gmail dot com
 */
public class Imaginary extends Fixed1ArgFunction implements FreeRefFunction {

    public static final FreeRefFunction instance = new Imaginary();

    public static final String GROUP1_REAL_SIGN_REGEX = "([+-]?)";
    public static final String GROUP2_REAL_INTEGER_OR_DOUBLE_REGEX = "([0-9]+\\.[0-9]+|[0-9]*)";
    public static final String GROUP3_IMAGINARY_SIGN_REGEX = "([+-]?)";
    public static final String GROUP4_IMAGINARY_INTEGER_OR_DOUBLE_REGEX = "([0-9]+\\.[0-9]+|[0-9]*)";
    public static final String GROUP5_IMAGINARY_GROUP_REGEX = "([ij]?)";

    public static final Pattern COMPLEX_NUMBER_PATTERN
            = Pattern.compile(GROUP1_REAL_SIGN_REGEX + GROUP2_REAL_INTEGER_OR_DOUBLE_REGEX +
            GROUP3_IMAGINARY_SIGN_REGEX + GROUP4_IMAGINARY_INTEGER_OR_DOUBLE_REGEX + GROUP5_IMAGINARY_GROUP_REGEX);

    public static final int GROUP1_REAL_SIGN = 1;
    public static final int GROUP2_IMAGINARY_INTEGER_OR_DOUBLE = 2;
    public static final int GROUP3_IMAGINARY_SIGN = 3;
    public static final int GROUP4_IMAGINARY_INTEGER_OR_DOUBLE = 4;

    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval inumberVE) {
        ValueEval veText1;
        try {
            veText1 = OperandResolver.getSingleValue(inumberVE, srcRowIndex, srcColumnIndex);
        } catch (EvaluationException e) {
            return e.getErrorEval();
        }
        String iNumber = OperandResolver.coerceValueToString(veText1);

        Matcher m = COMPLEX_NUMBER_PATTERN.matcher(iNumber);
        boolean result = m.matches();

        String imaginary = "";
        if (result == true) {
            String imaginaryGroup = m.group(5);
            boolean hasImaginaryPart = imaginaryGroup.equals("i") || imaginaryGroup.equals("j");

            if (imaginaryGroup.length() == 0) {
                return new StringEval(String.valueOf(0));
            }

            if (hasImaginaryPart) {
                String sign = "";
                String imaginarySign = m.group(GROUP3_IMAGINARY_SIGN);
                if (imaginarySign.length() != 0 && !(imaginarySign.equals("+"))) {
                    sign = imaginarySign;
                }

                String groupImaginaryNumber = m.group(GROUP4_IMAGINARY_INTEGER_OR_DOUBLE);
                if (groupImaginaryNumber.length() != 0) {
                    imaginary = sign + groupImaginaryNumber;
                } else {
                    imaginary = sign + "1";
                }
            }
        } else {
            return ErrorEval.NUM_ERROR;
        }

        return new StringEval(imaginary);
    }

    public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
        if (args.length != 1) {
            return ErrorEval.VALUE_INVALID;
        }
        return evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0]);
    }
}


text:
//
//  MTGeometry.m
//  MTGeometry
//
//  Created by Adam Kirk on 9/3/12.
//  Copyright (c) 2012 Mysterious Trousers. All rights reserved.
//

#import "MTGeometry.h"

#define MT_EPS      1e-4
#define MT_MIN(A,B)	({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
#define MT_MAX(A,B)	({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
#define MT_ABS(A)	({ __typeof__(A) __a = (A); __a < 0 ? -__a : __a; })

#pragma mark - Points

CGDelta CGDeltaMake(CGFloat deltaX, CGFloat deltaY)
{
	CGDelta delta;
	delta.x = deltaX;
	delta.y = deltaY;
	return delta;
}

CGFloat CGPointDistance(CGPoint p1, CGPoint p2)
{
    CGFloat dx = p1.x - p2.x;
    CGFloat dy = p1.y - p2.y;
    CGFloat dist = sqrt(pow(dx, 2) + pow(dy, 2));
    return dist;
}

CGPoint CGPointAlongLine(CGLine line, CGFloat distance)
{
    CGPoint start           = line.point1;
    CGPoint end             = line.point2;
    CGFloat totalDistance	= CGPointDistance(start, end);
	CGPoint totalDelta		= CGPointMake(end.x - start.x, end.y - start.y);
	CGFloat percent			= distance / totalDistance;
	CGPoint delta			= CGPointMake( totalDelta.x * percent, totalDelta.y * percent );
	return CGPointMake( start.x + delta.x, start.y + delta.y);
}

CGPoint CGPointRotatedAroundPoint(CGPoint point, CGPoint pivot, CGFloat degrees)
{
    CGAffineTransform translation, rotation;
	translation	= CGAffineTransformMakeTranslation(-pivot.x, -pivot.y);
	point		= CGPointApplyAffineTransform(point, translation);
	rotation	= CGAffineTransformMakeRotation(degrees * M_PI/180.0);
	point		= CGPointApplyAffineTransform(point, rotation);
	translation	= CGAffineTransformMakeTranslation(pivot.x, pivot.y);
	point		= CGPointApplyAffineTransform(point, translation);
	return point;
}

#pragma mark - Lines

CGLine CGLineMake(CGPoint point1, CGPoint point2)
{
	CGLine line;
	line.point1.x = point1.x;
	line.point1.y = point1.y;
	line.point2.x = point2.x;
	line.point2.y = point2.y;
	return line;
}

bool CGLineEqualToLine(CGLine line1, CGLine line2)
{
	return CGPointEqualToPoint(line1.point1, line2.point1) && CGPointEqualToPoint(line1.point2, line2.point2);
}

CGPoint CGLineMidPoint(CGLine line)
{
    CGPoint midPoint = CGPointZero;
	midPoint.x = (line.point1.x + line.point2.x) / 2.0;
	midPoint.y = (line.point1.y + line.point2.y) / 2.0;
	return midPoint;
}

CGPoint CGLinesIntersectAtPoint(CGLine line1, CGLine line2)
{
	CGFloat mua,mub;
	CGFloat denom,numera,numerb;

	double x1 = line1.point1.x;
	double y1 = line1.point1.y;
	double x2 = line1.point2.x;
	double y2 = line1.point2.y;
	double x3 = line2.point1.x;
	double y3 = line2.point1.y;
	double x4 = line2.point2.x;
	double y4 = line2.point2.y;

	denom  = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1);
	numera = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
	numerb = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);

	/* Are the lines coincident? */
	if (MT_ABS(numera) < MT_EPS && MT_ABS(numerb) < MT_EPS && MT_ABS(denom) < MT_EPS) {
		return CGPointMake( (x1 + x2) / 2.0 , (y1 + y2) / 2.0);
	}

	/* Are the line parallel */
	if (MT_ABS(denom) < MT_EPS) {
		return NULL_POINT;
	}

	/* Is the intersection along the the segments */
	mua = numera / denom;
	mub = numerb / denom;
	if (mua < 0 || mua > 1 || mub < 0 || mub > 1) {
		return NULL_POINT;
	}
	return CGPointMake(x1 + mua * (x2 - x1), y1 + mua * (y2 - y1));
}

CGFloat CGLineLength(CGLine line)
{
	return CGPointDistance(line.point1, line.point2);
}

CGLine CGLineScale(CGLine line, CGFloat scale)
{
	CGDelta lineDelta = CGLineDelta(line);
	CGFloat scaledDeltaX = lineDelta.x * scale;
	CGFloat scaledDeltaY = lineDelta.y * scale;
	return CGLineMake( CGPointMake(line.point1.x, line.point1.y), CGPointMake(line.point1.x + scaledDeltaX, line.point1.y + scaledDeltaY) );
}

CGLine CGLineTranslate(CGLine line, CGDelta delta)
{
    line.point1.x += delta.x;
    line.point1.y += delta.y;
    line.point2.x += delta.x;
    line.point2.y += delta.y;
    return line;
}

CGLine CGLineScaleOnMidPoint(CGLine line, CGFloat scale)
{
    CGPoint midPoint = CGLineMidPoint(line);
    CGLine scaledLine = CGLineScale(line, scale);
    CGPoint midScaled = CGPointMake(((scaledLine.point2.x - line.point2.x) / 2.0) + line.point2.x,
                                    ((scaledLine.point2.y - line.point2.y) / 2.0) + line.point2.y);
    CGPoint newStartPoint = CGPointRotatedAroundPoint(midScaled, midPoint, 180);
    return CGLineMake(newStartPoint, midScaled);
}

CGDelta CGLineDelta(CGLine line)
{
	return CGDeltaMake(line.point2.x - line.point1.x, line.point2.y - line.point1.y);
}

bool CGLinesAreParallel(CGLine line1, CGLine line2)
{
	CGFloat denom;

	double x1 = line1.point1.x;
	double y1 = line1.point1.y;
	double x2 = line1.point2.x;
	double y2 = line1.point2.y;
	double x3 = line2.point1.x;
	double y3 = line2.point1.y;
	double x4 = line2.point2.x;
	double y4 = line2.point2.y;

	denom  = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1);     // m1 - m2

	if (MT_ABS(denom) < MT_EPS) {
		return true;
	}
    else {
        return false;
    }
}

#pragma mark - Rectangles

CGPoint CGRectTopLeftPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
}

CGPoint CGRectTopRightPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
}

CGPoint CGRectBottomLeftPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
}

CGPoint CGRectBottomRightPoint(CGRect rect)
{
	return CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
}

CGRect CGRectResize(CGRect rect, CGSize newSize)
{
    CGFloat dx = (rect.size.width - newSize.width) / 2.0;
    CGFloat dy = (rect.size.height - newSize.height) / 2.0;
	return CGRectInset(rect, dx, dy);
}

CGRect CGRectInsetEdge(CGRect rect, CGRectEdge edge, CGFloat amount)
{
	if (edge == CGRectMinXEdge) {
		rect.origin.x += amount;
		rect.size.width -= amount;
	}
	else if (edge == CGRectMaxXEdge) {
		rect.size.width += amount;
	}
	else if (edge == CGRectMinYEdge) {
		rect.origin.y += amount;
		rect.size.height -= amount;
	}
	else if (edge == CGRectMaxYEdge) {
		rect.size.height += amount;
	}
	return rect;
}

CGRect CGRectStackedWithinRectFromEdge(CGRect rect, CGSize size, int count, CGRectEdge edge, bool reverse)
{
    int max_columns = floor(rect.size.width / size.width);
    int max_rows = floor(rect.size.height / size.height);

    if (edge == CGRectMinYEdge) {
        int current_row = floor(count / max_columns);
        int current_col = (count - 1) % max_columns;
        if (reverse) current_col = max_columns - (current_col + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMaxYEdge) {
        int current_row = floor(count / max_columns);
        int current_col = (count - 1) % max_columns;
        if (!reverse) current_col = max_columns - (current_col + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMaxY(rect) - size.height - (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMinXEdge) {
        int current_col = floor(count / max_columns);
        int current_row = (count - 1) % max_columns;
        if (!reverse) current_row = max_rows - (current_row + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMinX(rect) + (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + (current_row * size.height);
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    else if (edge == CGRectMaxXEdge) {
        int current_col = floor(count / max_columns);
        int current_row = (count - 1) % max_columns;
        if (reverse) current_row = max_rows - (current_row + 1);
        if (current_col > max_columns || current_row > max_rows) {
            return CGRectNull;
        }
        else {
            CGFloat x = CGRectGetMaxX(rect) - size.width - (current_col * size.width);
            CGFloat y = CGRectGetMinY(rect) + current_row * size.height;
            return CGRectMake(x, y, size.width, size.height);
        }
    }

    return CGRectNull;
}

CGPoint CGRectCenterPoint(CGRect rect)
{
    CGPoint centerPoint = CGPointZero;
    centerPoint.x = CGRectGetMidX(rect);
    centerPoint.y = CGRectGetMidY(rect);
    return centerPoint;
}

void CGRectClosestTwoCornerPoints(CGRect rect, CGPoint point, CGPoint *point1, CGPoint *point2)
{
	// gather the rects points
    CGPoint rectPoints[4];
    rectPoints[0] = CGPointMake(rect.origin.x, rect.origin.y);
    rectPoints[1] = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y);
    rectPoints[2] = CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
    rectPoints[3] = CGPointMake(rect.origin.x, rect.origin.y + rect.size.height);

    // bubble sort them
    int changed = 1;
    while (changed) {
        changed = 0;
        for (int i = 0; i < 3; i++) {
            CGPoint p1 = rectPoints[i];
            CGPoint p2 = rectPoints[i+1];
            if (CGPointDistance(point, p1) > CGPointDistance(point, p2)) {
                rectPoints[i] = p2;
                rectPoints[i+1] = p1;
                changed = 1;
            }
        }
    }

	// assign them to the passed in pointers
    *point1 = rectPoints[0];
    *point2 = rectPoints[1];
}

CGPoint CGLineIntersectsRectAtPoint(CGRect rect, CGLine line)
{
	CGLine top		= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ) );
	CGLine right	= CGLineMake( CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
	CGLine bottom	= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
	CGLine left		= CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ) );

	// ensure the line extends beyond outside the rectangle
	CGFloat topLeftToBottomRight = CGPointDistance(CGRectTopLeftPoint(rect), CGRectBottomRightPoint(rect));
	CGFloat bottomLeftToTopRight = CGPointDistance(CGRectBottomLeftPoint(rect), CGRectTopRightPoint(rect));
	CGFloat maxDimension = MT_MAX(topLeftToBottomRight, bottomLeftToTopRight);
	CGFloat scaleFactor = maxDimension / MT_MIN(CGLineLength(line), maxDimension);
	CGLine extendedLine = CGLineScale(line, scaleFactor + 3);

	CGPoint points[4] = { CGLinesIntersectAtPoint(top, extendedLine), CGLinesIntersectAtPoint(right, extendedLine), CGLinesIntersectAtPoint(bottom, extendedLine), CGLinesIntersectAtPoint(left, extendedLine) };

	for (int i = 0; i < 4; i++) {
		CGPoint p = points[i];
		if (!CGPointEqualToPoint(p, NULL_POINT)) {
			return p;
		}
	}

	return NULL_POINT;
}

#pragma mark - Arcs

void CGControlPointsForArcBetweenPointsWithRadius(CGPoint startPoint,
                                                  CGPoint endPoint,
                                                  CGFloat radius,
                                                  bool rightHandRule,
                                                  CGPoint *controlPoint1,
                                                  CGPoint *controlPoint2)
{
    CGLine line             = CGLineMake(startPoint, endPoint);
    CGPoint midPoint        = CGLineMidPoint(line);
    CGFloat degrees         = rightHandRule ? 90 : -90;
    CGPoint rotatedPoint    = CGPointRotatedAroundPoint(startPoint, midPoint, degrees);
    CGFloat lineLength      = CGLineLength(line);
    if (lineLength > radius * 2) {
        *controlPoint1 = CGPointMake(startPoint.x, startPoint.y);
        *controlPoint2 = CGPointMake(endPoint.x, endPoint.y);
        return;
    }
    CGFloat diameterPercent = lineLength / (radius * 2);
    CGLine perpLine         = CGLineMake(midPoint, rotatedPoint);
    CGLine arcMidLine       = CGLineScale(perpLine, diameterPercent);
    CGDelta arcMidLineDelta = CGLineDelta(arcMidLine);
    CGLine scaledLine       = CGLineScaleOnMidPoint(line, diameterPercent);
    CGLine translatedLine   = CGLineTranslate(scaledLine, arcMidLineDelta);
    *controlPoint1          = translatedLine.point1;
    *controlPoint2          = translatedLine.point2;
}


text:
- [Git](http://git-scm.com/downloads)
- [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
- [Maven](https://maven.apache.org/download.cgi)
- An IDE, for example [IntelliJ IDEA](https://www.jetbrains.com/idea/download/)
- [Spring Boot CLI](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#getting-started-installing-the-cli)

### Deploy and Manage
- Create a free account on [Pivotal Web Services](http://run.pivotal.io/)
- [Cloud Foundry CLI](https://github.com/cloudfoundry/cli/releases)