public void findPatterns () {
        PatternFinder patternFinder = new PatternFinder();
        // Iterate over trips and process each trip and its stop times.
        for (Trip trip : this.trips.values()) {
            Iterable<StopTime> orderedStopTimesForTrip = this.getOrderedStopTimesForTrip(trip.trip_id);
            patternFinder.processTrip(trip, orderedStopTimesForTrip);
        }
        Map<TripPatternKey, Pattern> patternObjects = patternFinder.createPatternObjects(this.stops, null);
        this.patterns.putAll(patternObjects.values().stream()
                .collect(Collectors.toMap(Pattern::getId, pattern -> pattern)));
    }

MapDB-based implementation to find patterns.

FIXME: Remove and make pattern finding happen during validation? We want to share the pattern finder between the
two implementations (MapDB and RDBMS), apply the same validation process to both kinds of storage, and produce
Patterns in the same way in both cases, during validation. This prevents us from iterating over every stopTime
twice, since we're already iterating over all of them in validation. However, in this case it might not be costly
to simply retrieve the stop times from the stop_times map.

MapDB - based implementation to find patterns .


public double getTripDistance (String trip_id, boolean straightLine) {
        return straightLine
                ? GeoUtils.getDistance(this.getStraightLineForStops(trip_id))
                : GeoUtils.getDistance(this.getTripGeometry(trip_id));
    }

public double getTripDistance ( String trip_id , boolean straightLine ) { return straightLine ? GeoUtils . getDistance ( this . getStraightLineForStops ( trip_id ) ) : GeoUtils . getDistance ( this . getTripGeometry ( trip_id ) ) ; }


public double getTripSpeed (String trip_id, boolean straightLine) {

        StopTime firstStopTime = this.stop_times.ceilingEntry(Fun.t2(trip_id, null)).getValue();
        StopTime lastStopTime = this.stop_times.floorEntry(Fun.t2(trip_id, Fun.HI)).getValue();

        // ensure that stopTime returned matches trip id (i.e., that the trip has stoptimes)
        if (!firstStopTime.trip_id.equals(trip_id) || !lastStopTime.trip_id.equals(trip_id)) {
            return Double.NaN;
        }

        double distance = getTripDistance(trip_id, straightLine);

        // trip time (in seconds)
        int time = lastStopTime.arrival_time - firstStopTime.departure_time;

        return distance / time; // meters per second
    }


public List<StopTime> getStopTimesForStop (String stop_id) {
        SortedSet<Tuple2<String, Tuple2>> index = this.stopStopTimeSet
                .subSet(new Tuple2<>(stop_id, null), new Tuple2(stop_id, Fun.HI));

        return index.stream()
                .map(tuple -> this.stop_times.get(tuple.b))
                .collect(Collectors.toList());
    }

public List < StopTime > getStopTimesForStop ( String stop_id ) { SortedSet < Tuple2 < String , Tuple2 > > index = this . stopStopTimeSet . subSet ( new Tuple2 <> ( stop_id , null ) , new Tuple2 ( stop_id , Fun . HI ) ) ; return index . stream ( ) . map ( tuple -> this . stop_times . get ( tuple . b ) ) . collect ( Collectors . toList ( ) ) ; }

Get list of stop_times for a given stop_id.

Get list of stop_times for a given stop_id .


public List<Service> getServicesForDate (LocalDate date) {
        String dateString = date.format(dateFormatter);
        SortedSet<Tuple2<String, String>> index = this.servicesPerDate
                .subSet(new Tuple2<>(dateString, null), new Tuple2(dateString, Fun.HI));

        return index.stream()
                .map(tuple -> this.services.get(tuple.b))
                .collect(Collectors.toList());
    }

public List < Service > getServicesForDate ( LocalDate date ) { String dateString = date . format ( dateFormatter ) ; SortedSet < Tuple2 < String , String > > index = this . servicesPerDate . subSet ( new Tuple2 <> ( dateString , null ) , new Tuple2 ( dateString , Fun . HI ) ) ; return index . stream ( ) . map ( tuple -> this . services . get ( tuple . b ) ) . collect ( Collectors . toList ( ) ) ; }

Get list of services for each date of service.

Get list of services for each date of service .


public ZoneId getAgencyTimeZoneForStop (String stop_id) {
        StopTime stopTime = getStopTimesForStop(stop_id).iterator().next();

        Trip trip = this.trips.get(stopTime.trip_id);
        Route route = this.routes.get(trip.route_id);
        Agency agency = route.agency_id != null ? this.agency.get(route.agency_id) : this.agency.get(0);

        return ZoneId.of(agency.agency_timezone);
    }

public ZoneId getAgencyTimeZoneForStop ( String stop_id ) { StopTime stopTime = getStopTimesForStop ( stop_id ) . iterator ( ) . next ( ) ; Trip trip = this . trips . get ( stopTime . trip_id ) ; Route route = this . routes . get ( trip . route_id ) ; Agency agency = route . agency_id != null ? this . agency . get ( route . agency_id ) : this . agency . get ( 0 ) ; return ZoneId . of ( agency . agency_timezone ) ; }

Get the likely time zone for a stop using the agency of the first stop time encountered for the stop.

Get the likely time zone for a stop using the agency of the first stop time encountered for the stop .


public Map<TripPatternKey, Pattern> createPatternObjects(Map<String, Stop> stopById, SQLErrorStorage errorStorage) {
        // Make pattern ID one-based to avoid any JS type confusion between an ID of zero vs. null value.
        int nextPatternId = 1;
        // Create an in-memory list of Patterns because we will later rename them before inserting them into storage.
        Map<TripPatternKey, Pattern> patterns = new HashMap<>();
        // TODO assign patterns sequential small integer IDs (may include route)
        for (TripPatternKey key : tripsForPattern.keySet()) {
            Collection<Trip> trips = tripsForPattern.get(key);
            Pattern pattern = new Pattern(key.stops, trips, null);
            // Overwrite long UUID with sequential integer pattern ID
            pattern.pattern_id = Integer.toString(nextPatternId++);
            // FIXME: Should associated shapes be a single entry?
            pattern.associatedShapes = new HashSet<>();
            trips.stream().forEach(trip -> pattern.associatedShapes.add(trip.shape_id));
            if (pattern.associatedShapes.size() > 1 && errorStorage != null) {
                // Store an error if there is more than one shape per pattern. Note: error storage is null if called via
                // MapDB implementation.
                // TODO: Should shape ID be added to trip pattern key?
                errorStorage.storeError(NewGTFSError.forEntity(
                        pattern,
                        NewGTFSErrorType.MULTIPLE_SHAPES_FOR_PATTERN)
                            .setBadValue(pattern.associatedShapes.toString()));
            }
            patterns.put(key, pattern);
        }
        // Name patterns before storing in SQL database.
        renamePatterns(patterns.values(), stopById);
        LOG.info("Total patterns: {}", tripsForPattern.keySet().size());
        return patterns;
    }

Once all trips have been processed, call this method to produce the final Pattern objects representing all the
unique sequences of stops encountered. Returns map of patterns to their keys so that downstream functions can
make use of trip pattern keys for constructing pattern stops or other derivative objects.

Once all trips have been processed call this method to produce the final Pattern objects representing all the unique sequences of stops encountered . Returns map of patterns to their keys so that downstream functions can make use of trip pattern keys for constructing pattern stops or other derivative objects .


private static void setAnywayTimer(Context context) {
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, IdleReceiver.class);
        intent.setAction(ACTION_TRIGGER_IDLE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
        final long nowElapsed = SystemClock.elapsedRealtime();
        final long when = nowElapsed + INACTIVITY_ANYWAY_THRESHOLD;
        compatSetWindow(am, AlarmManager.ELAPSED_REALTIME_WAKEUP, when, IDLE_WINDOW_SLOP, pendingIntent);
    }

private static void setAnywayTimer ( Context context ) { AlarmManager am = ( AlarmManager ) context . getSystemService ( Context . ALARM_SERVICE ) ; Intent intent = new Intent ( context , IdleReceiver . class ) ; intent . setAction ( ACTION_TRIGGER_IDLE ) ; PendingIntent pendingIntent = PendingIntent . getBroadcast ( context , 0 , intent , 0 ) ; final long nowElapsed = SystemClock . elapsedRealtime ( ) ; final long when = nowElapsed + INACTIVITY_ANYWAY_THRESHOLD ; compatSetWindow ( am , AlarmManager . ELAPSED_REALTIME_WAKEUP , when , IDLE_WINDOW_SLOP , pendingIntent ) ; }

We can't get idle broadcasts while the app is not running. Since our app will probably be
killed before the device becomes idle, let's set an alarm sometime in the future that will
force an idle check.

We can t get idle broadcasts while the app is not running . Since our app will probably be killed before the device becomes idle let s set an alarm sometime in the future that will force an idle check .


public static void enableReceiver(Context context) {
        IntentFilter filter = getFilter();
        sReceiver = new IdleReceiver();
        context.getApplicationContext().registerReceiver(sReceiver, filter);
    }

public static void enableReceiver ( Context context ) { IntentFilter filter = getFilter ( ) ; sReceiver = new IdleReceiver ( ) ; context . getApplicationContext ( ) . registerReceiver ( sReceiver , filter ) ; }

Call this as soon as we get a chance, it will be unregistered whenever our app is killed.

Call this as soon as we get a chance it will be unregistered whenever our app is killed .


void reportNewIdleState(Context context, boolean isIdle) {
        JobStore jobStore = JobStore.initAndGet(context);
        synchronized (jobStore) {
            ArraySet<JobStatus> jobs = jobStore.getJobs();
            for (int i = 0; i < jobs.size(); i++) {
                JobStatus ts = jobs.valueAt(i);
                ts.idleConstraintSatisfied.set(isIdle);
            }
        }
        startWakefulService(context, JobServiceCompat.maybeRunJobs(context));
    }

void reportNewIdleState ( Context context , boolean isIdle ) { JobStore jobStore = JobStore . initAndGet ( context ) ; synchronized ( jobStore ) { ArraySet < JobStatus > jobs = jobStore . getJobs ( ) ; for ( int i = 0 ; i < jobs . size ( ) ; i ++ ) { JobStatus ts = jobs . valueAt ( i ) ; ts . idleConstraintSatisfied . set ( isIdle ) ; } } startWakefulService ( context , JobServiceCompat . maybeRunJobs ( context ) ) ; }

Interaction with the task manager service


public boolean add(JobStatus jobStatus) {
        boolean replaced = mJobSet.remove(jobStatus);
        mJobSet.add(jobStatus);
        if (!jobStatus.isPersisted()) {
            markForBootSession(jobStatus);
        }
        maybeWriteStatusToDiskAsync();
        return replaced;
    }

public boolean add ( JobStatus jobStatus ) { boolean replaced = mJobSet . remove ( jobStatus ) ; mJobSet . add ( jobStatus ) ; if ( ! jobStatus . isPersisted ( ) ) { markForBootSession ( jobStatus ) ; } maybeWriteStatusToDiskAsync ( ) ; return replaced ; }

Add a job to the master list, persisting it if necessary. If the JobStatus already exists,
it will be replaced.

@param jobStatus Job to add.
@return Whether or not an equivalent JobStatus was replaced by this operation.

Add a job to the master list persisting it if necessary . If the JobStatus already exists it will be replaced .


public boolean containsJobId(int jobId) {
        for (int i = mJobSet.size() - 1; i >= 0; i--) {
            JobStatus ts = mJobSet.valueAt(i);
            if (ts.matches(jobId)) {
                return true;
            }
        }
        return false;
    }

public boolean containsJobId ( int jobId ) { for ( int i = mJobSet . size ( ) - 1 ; i >= 0 ; i -- ) { JobStatus ts = mJobSet . valueAt ( i ) ; if ( ts . matches ( jobId ) ) { return true ; } } return false ; }

Whether this jobStatus object already exists in the JobStore.

Whether this jobStatus object already exists in the JobStore .


public boolean remove(JobStatus jobStatus) {
        boolean removed = mJobSet.remove(jobStatus);
        if (!removed) {
            return false;
        }
        if (!jobStatus.isPersisted()) {
            unmarkForBootSession(jobStatus);
        }
        maybeWriteStatusToDiskAsync();
        return removed;
    }

public boolean remove ( JobStatus jobStatus ) { boolean removed = mJobSet . remove ( jobStatus ) ; if ( ! removed ) { return false ; } if ( ! jobStatus . isPersisted ( ) ) { unmarkForBootSession ( jobStatus ) ; } maybeWriteStatusToDiskAsync ( ) ; return removed ; }

Remove the provided job. Will also delete the job if it was persisted.

@return Whether or not the job existed to be removed.

Remove the provided job . Will also delete the job if it was persisted .


private JobStatus rescheduleFailedJob(JobStatus job) {
        if (job.hasIdleConstraint()) {
            // Don't need to modify time on idle job, it will run whenever the next idle period is.
            return job;
        }

        final long elapsedNowMillis = SystemClock.elapsedRealtime();
        final JobInfo jobInfo = job.getJob();

        final long initialBackoffMillis = jobInfo.getInitialBackoffMillis();
        final int backoffAttemps = job.getNumFailures() + 1;

        long delayMillis;
        switch (job.getJob().getBackoffPolicy()) {
            case JobInfo.BACKOFF_POLICY_LINEAR:
                delayMillis = initialBackoffMillis * backoffAttemps;
                break;
            default:
            case JobInfo.BACKOFF_POLICY_EXPONENTIAL:
                delayMillis = (long) Math.scalb(initialBackoffMillis, backoffAttemps - 1);
                break;
        }
        delayMillis = Math.min(delayMillis, JobInfo.MAX_BACKOFF_DELAY_MILLIS);
        return new JobStatus(job, elapsedNowMillis + delayMillis, JobStatus.NO_LATEST_RUNTIME, backoffAttemps);
    }

A job is rescheduled with exponential back-off if the client requests this from their
execution logic.
A caveat is for idle-mode jobs, for which the idle-mode constraint will usurp the
timeliness of the reschedule. For an idle-mode job, no deadline is given.
@return A newly instantiated JobStatus with the same constraints as the last job except
with adjusted timing constraints.

A job is rescheduled with exponential back - off if the client requests this from their execution logic . A caveat is for idle - mode jobs for which the idle - mode constraint will usurp the timeliness of the reschedule . For an idle - mode job no deadline is given .


@Override
    public void clear() {
        if (mSize != 0) {
            freeArrays(mHashes, mArray, mSize);
            mHashes = EmptyArray.INT;
            mArray = EmptyArray.OBJECT;
            mSize = 0;
        }
    }

@ Override public void clear ( ) { if ( mSize != 0 ) { freeArrays ( mHashes , mArray , mSize ) ; mHashes = EmptyArray . INT ; mArray = EmptyArray . OBJECT ; mSize = 0 ; } }

Make the array map empty. All storage is released.

Make the array map empty . All storage is released .


public void onReceivedStartJob(JobParameters params) {
        mShowStartView.setBackgroundColor(startJobColor);
        Message m = Message.obtain(mHandler, MSG_UNCOLOUR_START);
        mHandler.sendMessageDelayed(m, 1000L); // uncolour in 1 second.
        mParamsTextView.setText("Executing: " + params.getJobId() + " " + params.getExtras());
    }

public
void
onReceivedStartJob
(
JobParameters
params
)
{
mShowStartView
.
setBackgroundColor
(
startJobColor
)
;
Message
m
=
Message
.
obtain
(
mHandler
,
MSG_UNCOLOUR_START
)
;
mHandler
.
sendMessageDelayed
(
m
,
1000L
)
;
// uncolour in 1 second.
mParamsTextView
.
setText
(
"Executing: "
+
params
.
getJobId
(
)
+
" "
+
params
.
getExtras
(
)
)
;
}

Receives callback from the service when a job has landed on the app. Colours the UI and post
a message to uncolour it after a second.

Receives callback from the service when a job has landed on the app . Colours the UI and post a message to uncolour it after a second .


public void onReceivedStopJob() {
        mShowStopView.setBackgroundColor(stopJobColor);
        Message m = Message.obtain(mHandler, MSG_UNCOLOUR_STOP);
        mHandler.sendMessageDelayed(m, 2000L); // uncolour in 1 second.
        mParamsTextView.setText("");
    }

public
void
onReceivedStopJob
(
)
{
mShowStopView
.
setBackgroundColor
(
stopJobColor
)
;
Message
m
=
Message
.
obtain
(
mHandler
,
MSG_UNCOLOUR_STOP
)
;
mHandler
.
sendMessageDelayed
(
m
,
2000L
)
;
// uncolour in 1 second.
mParamsTextView
.
setText
(
""
)
;
}

Receives callback from the service when a job that previously landed on the app must stop
executing. Colours the UI and post a message to uncolour it after a second.

Receives callback from the service when a job that previously landed on the app must stop executing . Colours the UI and post a message to uncolour it after a second .


private static boolean canStopTrackingJob(JobStatus job) {
        return (!job.hasTimingDelayConstraint() ||
                job.timeDelayConstraintSatisfied.get()) &&
                (!job.hasDeadlineConstraint() ||
                        job.deadlineConstraintSatisfied.get());
    }

private static boolean canStopTrackingJob ( JobStatus job ) { return ( ! job . hasTimingDelayConstraint ( ) || job . timeDelayConstraintSatisfied . get ( ) ) && ( ! job . hasDeadlineConstraint ( ) || job . deadlineConstraintSatisfied . get ( ) ) ; }

Determines whether this controller can stop tracking the given job.
The controller is no longer interested in a job once its time constraint is satisfied, and
the job's deadline is fulfilled - unlike other controllers a time constraint can't toggle
back and forth.

Determines whether this controller can stop tracking the given job . The controller is no longer interested in a job once its time constraint is satisfied and the job s deadline is fulfilled - unlike other controllers a time constraint can t toggle back and forth .


public void putString(String key, String value) {
        PersistableBundleCompat.putString(bundle, key, value);
    }

public void putString ( String key , String value ) { PersistableBundleCompat . putString ( bundle , key , value ) ; }

Inserts a String value into the mapping of this Bundle, replacing any existing value for the
given key.  Either key or value may be null.

@param key   a String, or null
@param value a String, or null

Inserts a String value into the mapping of this Bundle replacing any existing value for the given key . Either key or value may be null .


public void putStringArray(String key, String[] value) {
        PersistableBundleCompat.putStringArray(bundle, key, value);
    }

public void putStringArray ( String key , String [ ] value ) { PersistableBundleCompat . putStringArray ( bundle , key , value ) ; }

Inserts a String array value into the mapping of this Bundle, replacing any existing value
for the given key.  Either key or value may be null.

@param key   a String, or null
@param value a String array object, or null

Inserts a String array value into the mapping of this Bundle replacing any existing value for the given key . Either key or value may be null .


public String getString(String key, String defaultValue) {
        return PersistableBundleCompat.getString(bundle, key, defaultValue);
    }

public String getString ( String key , String defaultValue ) { return PersistableBundleCompat . getString ( bundle , key , defaultValue ) ; }

Returns the value associated with the given key, or defaultValue if no mapping of the desired
type exists for the given key or if a null value is explicitly associated with the given
key.

@param key          a String, or null
@param defaultValue Value to return if key does not exist or if a null value is associated
with the given key.
@return the String value associated with the given key, or defaultValue if no valid String
object is currently mapped to that key.

Returns the value associated with the given key or defaultValue if no mapping of the desired type exists for the given key or if a null value is explicitly associated with the given key .


public void putPersistableBundle(String key, PersistableBundle value) {
        PersistableBundleCompat.putPersistableBundle(bundle, key, value.bundle);
    }

public void putPersistableBundle ( String key , PersistableBundle value ) { PersistableBundleCompat . putPersistableBundle ( bundle , key , value . bundle ) ; }

Inserts a PersistableBundle value into the mapping of this Bundle, replacing any existing
value for the given key.  Either key or value may be null.

@param key   a String, or null
@param value a Bundle object, or null

Inserts a PersistableBundle value into the mapping of this Bundle replacing any existing value for the given key . Either key or value may be null .


public void writeToParcel(Parcel out, int flags) {
        out.writeString(mMessage);
        out.writeString(mActionMessage);
        out.writeInt(mActionIcon);
        out.writeParcelable(mToken, 0);
        out.writeInt((int) mDuration);
        out.writeParcelable(mBtnTextColor, 0);
        out.writeParcelable(mBackgroundColor, 0);
        out.writeInt(mHeight);
        out.writeValue(mTypeface);
    }

public void writeToParcel ( Parcel out , int flags ) { out . writeString ( mMessage ) ; out . writeString ( mActionMessage ) ; out . writeInt ( mActionIcon ) ; out . writeParcelable ( mToken , 0 ) ; out . writeInt ( ( int ) mDuration ) ; out . writeParcelable ( mBtnTextColor , 0 ) ; out . writeParcelable ( mBackgroundColor , 0 ) ; out . writeInt ( mHeight ) ; out . writeValue ( mTypeface ) ; }


public int getHeight() {
        mParentView.measure(View.MeasureSpec.makeMeasureSpec(mParentView.getWidth(), View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(mParentView.getHeight(), View.MeasureSpec.AT_MOST));
        return mParentView.getMeasuredHeight();
    }

public int getHeight ( ) { mParentView . measure ( View . MeasureSpec . makeMeasureSpec ( mParentView . getWidth ( ) , View . MeasureSpec . EXACTLY ) , View . MeasureSpec . makeMeasureSpec ( mParentView . getHeight ( ) , View . MeasureSpec . AT_MOST ) ) ; return mParentView . getMeasuredHeight ( ) ; }

Calculates the height of the SnackBar

@return the height of the SnackBar


public static void dPrint(String str) {
        if (verbosePrint) {
            System.out.println(str);
        }
        M_log.fine(str);
    }

public static void dPrint ( String str ) { if ( verbosePrint ) { System . out . println ( str ) ; } M_log . fine ( str ) ; }


public static boolean checkProperties(Properties postProp, String url,
            String method, String oauth_consumer_key, String oauth_consumer_secret) {

        return checkProperties(convertToMap(postProp), url, method,
                oauth_consumer_key, oauth_consumer_secret);
    }

public static boolean checkProperties ( Properties postProp , String url , String method , String oauth_consumer_key , String oauth_consumer_secret ) { return checkProperties ( convertToMap ( postProp ) , url , method , oauth_consumer_key , oauth_consumer_secret ) ; }

Check if the properties are properly signed

@deprecated See:
{@link BasicLTIUtil#checkProperties(Map, String, String, String, String)}

@param postProp
@param url
@param method
@param oauth_consumer_key
@param oauth_consumer_secret
@return


public static boolean checkProperties(
            Map<String, String> postProp, String url, String method,
            String oauth_consumer_key, String oauth_consumer_secret) {

        OAuthMessage oam = new OAuthMessage(method, url, postProp.entrySet());
        OAuthConsumer cons = new OAuthConsumer("about:blank", oauth_consumer_key,
                oauth_consumer_secret, null);
        OAuthValidator oav = new SimpleOAuthValidator();

        OAuthAccessor acc = new OAuthAccessor(cons);

        String base_string = null;
        try {
            base_string = OAuthSignatureMethod.getBaseString(oam);
        } catch (Exception e) {
            M_log.warning(e.getLocalizedMessage());
            base_string = null;
            return false;
        }

        try {
            oav.validateMessage(oam, acc);
        } catch (Exception e) {
            M_log.warning("Provider failed to validate message");
            M_log.warning(e.getLocalizedMessage());
            if (base_string != null) {
                M_log.warning(base_string);
            }
            return false;
        }
        return true;
    }

public
static
boolean
checkProperties
(
Map
<
String
,
String
>
postProp
,
String
url
,
String
method
,
String
oauth_consumer_key
,
String
oauth_consumer_secret
)
{
OAuthMessage
oam
=
new
OAuthMessage
(
method
,
url
,
postProp
.
entrySet
(
)
)
;
OAuthConsumer
cons
=
new
OAuthConsumer
(
"about:blank"
,
oauth_consumer_key
,
oauth_consumer_secret
,
)
;
OAuthValidator
oav
=
new
SimpleOAuthValidator
(
)
;
OAuthAccessor
acc
=
new
OAuthAccessor
(
cons
)
;
String
base_string
=
;
try
{
base_string
=
OAuthSignatureMethod
.
getBaseString
(
oam
)
;
}
catch
(
Exception
e
)
{
M_log
.
warning
(
e
.
getLocalizedMessage
(
)
)
;
base_string
=
;
return
false
;
}
try
{
oav
.
validateMessage
(
oam
,
acc
)
;
}
catch
(
Exception
e
)
{
M_log
.
warning
(
"Provider failed to validate message"
)
;
M_log
.
warning
(
e
.
getLocalizedMessage
(
)
)
;
if
(
base_string
!=
)
{
M_log
.
warning
(
base_string
)
;
}
return
false
;
}
return
true
;
}

Check if the fields are properly signed

@param postProp
@param url
@param method
@param oauth_consumer_key
@param oauth_consumer_secret

@return


public static String prepareForExport(String descriptor) {
        Map<String, Object> tm = null;
        try {
            tm = XMLMap.getFullMap(descriptor.trim());
        } catch (Exception e) {
            M_log.warning("BasicLTIUtil exception parsing BasicLTI descriptor"
                    + e.getMessage());
            return null;
        }
        if (tm == null) {
            M_log.warning("Unable to parse XML in prepareForExport");
            return null;
        }
        XMLMap.removeSubMap(tm, "/basic_lti_link/x-secure");
        String retval = XMLMap.getXML(tm, true);
        return retval;
    }

Remove fields that should not be exported


public static void setProperty(Properties props, String key, String value) {
        if (value == null) {
            return;
        }
        if (value.trim().length() < 1) {
            return;
        }
        props.setProperty(key, value);
    }

public static void setProperty ( Properties props , String key , String value ) { if ( value == null ) { return ; } if ( value . trim ( ) . length ( ) < 1 ) { return ; } props . setProperty ( key , value ) ; }

Mutates the passed Properties props variable. Puts the key,value into the
Map if the value is not null and is not empty.

@deprecated See: {@link #setProperty(Map, String, String)}
@param props Variable is mutated by this method.
@param key
@param value

Mutates the passed Properties props variable . Puts the key value into the Map if the value is not null and is not empty .


public static String htmlspecialchars(String input) {
        if (input == null) {
            return null;
        }
        String retval = input.replace("&", "&");
        retval = retval.replace("\"", """);
        retval = retval.replace("<", "<");
        retval = retval.replace(">", ">");
        retval = retval.replace(">", ">");
        retval = retval.replace("=", "=");
        return retval;
    }

public static String htmlspecialchars ( String input ) { if ( input == null ) { return null ; } String retval = input . replace ( "&" , "&" ) ; retval = retval . replace ( "\"" , """ ) ; retval = retval . replace ( "<" , "<" ) ; retval = retval . replace ( ">" , ">" ) ; retval = retval . replace ( ">" , ">" ) ; retval = retval . replace ( "=" , "=" ) ; return retval ; }

Basic utility to encode form text - handle the "safe cases"

Basic utility to encode form text - handle the safe cases


static public String getRealPath(String servletUrl, String extUrl) {
        Pattern pat = Pattern.compile("^https??://[^/]*");
        // Deal with potential bad extUrl formats
        Matcher m = pat.matcher(extUrl);
        if (m.find()) {
            extUrl = m.group(0);
        }

        String retval = pat.matcher(servletUrl).replaceFirst(extUrl);
        return retval;
    }

Simple utility method deal with a request that has the wrong URL when
behind a proxy.

@param extUrl The url that the external world sees us as responding to.
This needs to be up to but not including the last slash like and not
include any path information http://www.sakaiproject.org - although we do
compensate for extra stuff at the end.
@return The full path of the request with extUrl in place of whatever the
request thinks is the current URL.

Simple utility method deal with a request that has the wrong URL when behind a proxy .


@Override
    public LtiVerificationResult verify(HttpServletRequest request, String secret) throws LtiVerificationException {
        OAuthMessage oam = OAuthServlet.getMessage(request, OAuthServlet.getRequestURL(request));
        String oauth_consumer_key = null;
        try {
            oauth_consumer_key = oam.getConsumerKey();
        } catch (Exception e) {
            return new LtiVerificationResult(false, LtiError.BAD_REQUEST, "Unable to find consumer key in message");
        }

        OAuthValidator oav = new SimpleOAuthValidator();
        OAuthConsumer cons = new OAuthConsumer(null, oauth_consumer_key, secret, null);
        OAuthAccessor acc = new OAuthAccessor(cons);

        try {
            oav.validateMessage(oam, acc);
        } catch (Exception e) {
            return new LtiVerificationResult(false, LtiError.BAD_REQUEST, "Failed to validate: " + e.getLocalizedMessage());
        }
        return new LtiVerificationResult(true, new LtiLaunch(request));
    }

This method verifies the signed HttpServletRequest
@param request the HttpServletRequest that will be verified
@param secret the secret to verify the properties with
@return the result of the verification, along with contextual
information
@throws LtiVerificationException


@Override
    public LtiVerificationResult verifyParameters(Map<String, String> parameters, String url, String method, String secret) throws LtiVerificationException {
        OAuthMessage oam = new OAuthMessage(method, url, parameters.entrySet());
        OAuthConsumer cons = new OAuthConsumer(null, parameters.get(OAUTH_KEY_PARAMETER), secret, null);
        OAuthValidator oav = new SimpleOAuthValidator();
        OAuthAccessor acc = new OAuthAccessor(cons);

        try {
            oav.validateMessage(oam, acc);
        } catch (Exception e) {
            return new LtiVerificationResult(false, LtiError.BAD_REQUEST, "Failed to validate: " + e.getLocalizedMessage() + ", Parameters: " + Arrays.toString(parameters.entrySet().toArray()));
        }
        return new LtiVerificationResult(true, new LtiLaunch(parameters));
    }

@
Override
public
LtiVerificationResult
verifyParameters
(
Map
<
String
,
String
>
parameters
,
String
url
,
String
method
,
String
secret
)
throws
LtiVerificationException
{
OAuthMessage
oam
=
new
OAuthMessage
(
method
,
url
,
parameters
.
entrySet
(
)
)
;
OAuthConsumer
cons
=
new
OAuthConsumer
(
,
parameters
.
get
(
OAUTH_KEY_PARAMETER
)
,
secret
,
)
;
OAuthValidator
oav
=
new
SimpleOAuthValidator
(
)
;
OAuthAccessor
acc
=
new
OAuthAccessor
(
cons
)
;
try
{
oav
.
validateMessage
(
oam
,
acc
)
;
}
catch
(
Exception
e
)
{
return
new
LtiVerificationResult
(
false
,
LtiError
.
BAD_REQUEST
,
"Failed to validate: "
+
e
.
getLocalizedMessage
(
)
+
", Parameters: "
+
Arrays
.
toString
(
parameters
.
entrySet
(
)
.
toArray
(
)
)
)
;
}
return
new
LtiVerificationResult
(
true
,
new
LtiLaunch
(
parameters
)
)
;
}

This method will verify a collection of parameters
@param parameters the parameters that will be verified. mapped by key & value
@param url the url this request was made at
@param method the method this url was requested with
@param secret the secret to verify the propertihes with
@return
@throws LtiVerificationException


public void validateRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request)
	{
		validateRequest(oauth_consumer_key, oauth_secret, request, null) ;
	}

public void validateRequest ( String oauth_consumer_key , String oauth_secret , HttpServletRequest request ) { validateRequest ( oauth_consumer_key , oauth_secret , request , null ) ; }


@SuppressWarnings("unused")
	protected void doLaunch(HttpServletRequest request, HttpServletResponse response)
	{

		String profile = PERSIST.get("profile");
		response.setContentType("text/html");

		String output = null;
		if ( profile == null ) {
			output = "Missing profile";
		} else {
	        JSONObject providerProfile = (JSONObject) JSONValue.parse(profile);

			List<Properties> profileTools = new ArrayList<Properties> ();
	        Properties info = new Properties();
			String retval = LTI2Util.parseToolProfile(profileTools, info, providerProfile);
			String launch = null;
			String parameter = null;
			for ( Properties profileTool : profileTools ) {
				launch = (String) profileTool.get("launch");
				parameter = (String) profileTool.get("parameter");
			}
			JSONObject security_contract = (JSONObject) providerProfile.get(LTI2Constants.SECURITY_CONTRACT);

			String shared_secret = (String) security_contract.get(LTI2Constants.SHARED_SECRET);
			System.out.println("launch="+launch);
			System.out.println("shared_secret="+shared_secret);

			Properties ltiProps = LTI2SampleData.getLaunch();
			ltiProps.setProperty(BasicLTIConstants.LTI_VERSION,BasicLTIConstants.LTI_VERSION_2);

			Properties lti2subst = LTI2SampleData.getSubstitution();
			String settings_url = getServiceURL(request) + SVC_Settings + "/";
			lti2subst.setProperty("LtiLink.custom.url", settings_url + LTI2Util.SCOPE_LtiLink + "/"
					+ ltiProps.getProperty(BasicLTIConstants.RESOURCE_LINK_ID));
			lti2subst.setProperty("ToolProxyBinding.custom.url", settings_url + LTI2Util.SCOPE_ToolProxyBinding + "/"
					+ ltiProps.getProperty(BasicLTIConstants.CONTEXT_ID));
			lti2subst.setProperty("ToolProxy.custom.url", settings_url + LTI2Util.SCOPE_ToolProxy + "/"
					+ TEST_KEY);
			lti2subst.setProperty("Result.url", getServiceURL(request) + SVC_Result + "/"
					+ ltiProps.getProperty(BasicLTIConstants.RESOURCE_LINK_ID));

			// Do the substitutions
			Properties custom = new Properties();
			LTI2Util.mergeLTI2Parameters(custom, parameter);
			LTI2Util.substituteCustom(custom, lti2subst);

			// Place the custom values into the launch
			LTI2Util.addCustomToLaunch(ltiProps, custom);

			ltiProps = BasicLTIUtil.signProperties(ltiProps, launch, "POST",
                TEST_KEY, shared_secret, null, null, null);

			boolean dodebug = true;
			output = BasicLTIUtil.postLaunchHTML(ltiProps, launch, dodebug);
		}

		try {
			PrintWriter out = response.getWriter();
			out.println(output);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}


protected ToolConsumer buildToolConsumerProfile(HttpServletRequest request, Map<String, Object> deploy, String profile_id)
	{
		// Load the configuration data
		LTI2Config cnf = new org.imsglobal.lti2.LTI2ConfigSample();

		ToolConsumer consumer = new ToolConsumer(profile_id, "LTI-2p0", getServiceURL(request), cnf);

		// Normally we would check permissions before we offer capabilities
		List<String> capabilities = consumer.getCapability_offered();
		LTI2Util.allowEmail(capabilities);
		LTI2Util.allowName(capabilities);
		LTI2Util.allowSettings(capabilities);
		LTI2Util.allowResult(capabilities);

		// Normally we would check permissions before we offer services
		List<ServiceOffered> services = consumer.getService_offered();
		services.add(StandardServices.LTI2Registration(getServiceURL(request) +
			SVC_tc_registration + "/" + profile_id));
		services.add(StandardServices.LTI2ResultItem(getServiceURL(request) +
			SVC_Result + "/{" + BasicLTIConstants.LIS_RESULT_SOURCEDID + "}"));
		services.add(StandardServices.LTI2LtiLinkSettings(getServiceURL(request) +
			SVC_Settings + "/" + LTI2Util.SCOPE_LtiLink + "/{" + BasicLTIConstants.RESOURCE_LINK_ID + "}"));
		services.add(StandardServices.LTI2ToolProxySettings(getServiceURL(request) +
			SVC_Settings + "/" + LTI2Util.SCOPE_ToolProxyBinding + "/{" + BasicLTIConstants.CONTEXT_ID + "}"));
		services.add(StandardServices.LTI2ToolProxySettings(getServiceURL(request) +
			SVC_Settings + "/" + LTI2Util.SCOPE_ToolProxy + "/{" + LTI2Constants.TOOL_PROXY_GUID + "}"));
		return consumer;
	}

it is always null and we allow everything


public static String validateServices(ToolConsumer consumer, JSONObject providerProfile)
	{
		// Mostly to catch casting errors from bad JSON
		try {
			JSONObject security_contract = (JSONObject) providerProfile.get(LTI2Constants.SECURITY_CONTRACT);
			if ( security_contract == null  ) {
				return "JSON missing security_contract";
			}
			JSONArray tool_services = (JSONArray) security_contract.get(LTI2Constants.TOOL_SERVICE);

			List<ServiceOffered> services_offered = consumer.getService_offered();

			if ( tool_services != null ) for (Object o : tool_services) {
				JSONObject tool_service = (JSONObject) o;
				String json_service = (String) tool_service.get(LTI2Constants.SERVICE);

				boolean found = false;
				for (ServiceOffered service : services_offered ) {
					String service_endpoint = service.getEndpoint();
					if ( service_endpoint.equals(json_service) ) {
						found = true;
						break;
					}
				}
				if ( ! found ) return "Service not allowed: "+json_service;
			}
			return null;
		}
		catch (Exception e) {
			return "Exception:"+ e.getLocalizedMessage();
		}
	}

Validate the incoming tool_services against a tool consumer


public static String validateCapabilities(ToolConsumer consumer, JSONObject providerProfile)
	{
		List<Properties> theTools = new ArrayList<Properties> ();
		Properties info = new Properties();

		// Mostly to catch casting errors from bad JSON
		try {
			String retval = parseToolProfile(theTools, info, providerProfile);
			if ( retval != null )  return retval;

			if ( theTools.size() < 1 ) return "No tools found in profile";

			// Check all the capabilities requested by all the tools comparing against consumer
			List<String> capabilities = consumer.getCapability_offered();
			for ( Properties theTool : theTools ) {
				String ec = (String) theTool.get("enabled_capability");
				JSONArray enabled_capability = (JSONArray) JSONValue.parse(ec);
				if ( enabled_capability != null ) for (Object o : enabled_capability) {
					ec = (String) o;
					if ( capabilities.contains(ec) ) continue;
					return "Capability not permitted="+ec;
				}
			}
			return null;
		}
		catch (Exception e ) {
			return "Exception:"+ e.getLocalizedMessage();
		}
	}

Validate incoming capabilities requested against out ToolConsumer


public static void addCustomToLaunch(Properties ltiProps, Properties custom)
	{
        Enumeration<?> e = custom.propertyNames();
        while (e.hasMoreElements()) {
            String keyStr = (String) e.nextElement();
            String value =  custom.getProperty(keyStr);
            setProperty(ltiProps,"custom_"+keyStr,value);
        }
	}

public static void addCustomToLaunch ( Properties ltiProps , Properties custom ) { Enumeration < ? > e = custom . propertyNames ( ) ; while ( e . hasMoreElements ( ) ) { String keyStr = ( String ) e . nextElement ( ) ; String value = custom . getProperty ( keyStr ) ; setProperty ( ltiProps , "custom_" + keyStr , value ) ; } }


private void toogleListView(View v) {
        if (mLastViewTouchId != v.getId()) {
            if (mLastViewTouchId == mListViewLeft.getId()) {
                isLeftListEnabled = true;
                isRightListEnabled = false;
            } else {
                isLeftListEnabled = false;
                isRightListEnabled = true;
            }
        }
    }

private void toogleListView ( View v ) { if ( mLastViewTouchId != v . getId ( ) ) { if ( mLastViewTouchId == mListViewLeft . getId ( ) ) { isLeftListEnabled = true ; isRightListEnabled = false ; } else { isLeftListEnabled = false ; isRightListEnabled = true ; } } }

Each time we touch the opposite ListView than the last one we have selected
we need to activate it as the enable one


@Override
    public void onListScroll(View view, float deltaY) {
        int speed;
        if (view.getId() == mListViewLeft.getId() && !isLeftListEnabled) {
            speed = getSpeed(false, deltaY);

            mListViewRight.smoothScrollBy(speed, 0);
        } else if (view.getId() == mListViewRight.getId() && !isRightListEnabled) {
            speed = getSpeed(true, deltaY);
            mListViewLeft.smoothScrollBy(speed, 0);
        }
    }

@ Override public void onListScroll ( View view , float deltaY ) { int speed ; if ( view . getId ( ) == mListViewLeft . getId ( ) && ! isLeftListEnabled ) { speed = getSpeed ( false , deltaY ) ; mListViewRight . smoothScrollBy ( speed , 0 ) ; } else if ( view . getId ( ) == mListViewRight . getId ( ) && ! isRightListEnabled ) { speed = getSpeed ( true , deltaY ) ; mListViewLeft . smoothScrollBy ( speed , 0 ) ; } }

Receives the distance scroll on listView.

Receives the distance scroll on listView .


public static SafeUrlProto toProto(SafeUrl url) {
    return SafeUrlProto.newBuilder()
        .setPrivateDoNotAccessOrElseSafeUrlWrappedValue(url.getSafeUrlString())
        .build();
  }

Serializes a SafeUrl into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a SafeUrl using
{@link #fromProto(SafeUrlProto)}.

Serializes a SafeUrl into its opaque protocol message representation .


public static SafeStyleProto toProto(SafeStyle style) {
    return SafeStyleProto.newBuilder()
        .setPrivateDoNotAccessOrElseSafeStyleWrappedValue(style.getSafeStyleString()).build();
  }

Serializes a SafeStyle into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a SafeStyle using
{@link #fromProto(SafeStyleProto)}.

Serializes a SafeStyle into its opaque protocol message representation .


public static SafeScriptProto toProto(SafeScript script) {
    return SafeScriptProto.newBuilder()
        .setPrivateDoNotAccessOrElseSafeScriptWrappedValue(script.getSafeScriptString()).build();
  }

Serializes a SafeScript into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a SafeScript using
{@link #fromProto(SafeScriptProto)}.

Serializes a SafeScript into its opaque protocol message representation .


public static SafeStyleSheetProto toProto(SafeStyleSheet style) {
    return SafeStyleSheetProto.newBuilder()
        .setPrivateDoNotAccessOrElseSafeStyleSheetWrappedValue(
            style.getSafeStyleSheetString())
        .build();
  }

Serializes a SafeStyleSheet into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a SafeStyleSheet using
{@link #fromProto(SafeStyleSheetProto)}.

Serializes a SafeStyleSheet into its opaque protocol message representation .


public static TrustedResourceUrlProto toProto(TrustedResourceUrl url) {
    return TrustedResourceUrlProto.newBuilder()
        .setPrivateDoNotAccessOrElseTrustedResourceUrlWrappedValue(
            url.getTrustedResourceUrlString())
        .build();
  }

Serializes a TrustedResourceUrl into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a TrustedResourceUrl using
{@link #fromProto(TrustedResourceUrlProto)}.

Serializes a TrustedResourceUrl into its opaque protocol message representation .


public static SafeHtmlProto toProto(SafeHtml safeHtml) {
    return SafeHtmlProto.newBuilder().setPrivateDoNotAccessOrElseSafeHtmlWrappedValue(
        safeHtml.getSafeHtmlString()).build();
  }

Serializes a SafeHtml into its opaque protocol message representation.

<p>Protocol message forms of this type are intended to be opaque. The fields of the returned
protocol message should be considered encapsulated and are not intended for direct inspection
or manipulation. Protocol messages can be converted back into a SafeHtml using
{@link #fromProto(SafeHtmlProto)}.

Serializes a SafeHtml into its opaque protocol message representation .


public static double wrapAngleRad(double angle) {
        angle %= TrigMath.TWO_PI;
        if (angle <= -TrigMath.PI) {
            return angle + TrigMath.TWO_PI;
        }
        if (angle > TrigMath.PI) {
            return angle - TrigMath.TWO_PI;
        }
        return angle;
    }

public static double wrapAngleRad ( double angle ) { angle %= TrigMath . TWO_PI ; if ( angle <= - TrigMath . PI ) { return angle + TrigMath . TWO_PI ; } if ( angle > TrigMath . PI ) { return angle - TrigMath . TWO_PI ; } return angle ; }

Wraps the radian between -PI and PI

@param angle to wrap
@return -PI < radian <= PI


public static double round(double input, int decimals) {
        final double p = Math.pow(10, decimals);
        return Math.round(input * p) / p;
    }

public static double round ( double input , int decimals ) { final double p = Math . pow ( 10 , decimals ) ; return Math . round ( input * p ) / p ; }

Rounds a number to the amount of decimals specified

@param input to round
@param decimals to round to
@return the rounded number


public static double lerp(double x, double x1, double x2, double q0, double q1) {
        return ((x2 - x) / (x2 - x1)) * q0 + ((x - x1) / (x2 - x1)) * q1;
    }

public static double lerp ( double x , double x1 , double x2 , double q0 , double q1 ) { return ( ( x2 - x ) / ( x2 - x1 ) ) * q0 + ( ( x - x1 ) / ( x2 - x1 ) ) * q1 ; }

Calculates the value at x using linear interpolation

@param x the X coord of the value to interpolate
@param x1 the X coord of q0
@param x2 the X coord of q1
@param q0 the first known value (x1)
@param q1 the second known value (x2)
@return the interpolated value


public static Quaternionf slerp(Quaternionf a, Quaternionf b, float percent) {
        final float inverted;
        float cosineTheta = a.dot(b);
        if (cosineTheta < 0) {
            cosineTheta = -cosineTheta;
            inverted = -1;
        } else {
            inverted = 1;
        }
        if (1 - cosineTheta < GenericMath.FLT_EPSILON) {
            return a.mul(1 - percent).add(b.mul(percent * inverted));
        }
        final float theta = (float) TrigMath.acos(cosineTheta);
        final float sineTheta = TrigMath.sin(theta);
        final float coefficient1 = TrigMath.sin((1 - percent) * theta) / sineTheta;
        final float coefficient2 = TrigMath.sin(percent * theta) / sineTheta * inverted;
        return a.mul(coefficient1).add(b.mul(coefficient2));
    }

public static Quaternionf slerp ( Quaternionf a , Quaternionf b , float percent ) { final float inverted ; float cosineTheta = a . dot ( b ) ; if ( cosineTheta < 0 ) { cosineTheta = - cosineTheta ; inverted = - 1 ; } else { inverted = 1 ; } if ( 1 - cosineTheta < GenericMath . FLT_EPSILON ) { return a . mul ( 1 - percent ) . add ( b . mul ( percent * inverted ) ) ; } final float theta = ( float ) TrigMath . acos ( cosineTheta ) ; final float sineTheta = TrigMath . sin ( theta ) ; final float coefficient1 = TrigMath . sin ( ( 1 - percent ) * theta ) / sineTheta ; final float coefficient2 = TrigMath . sin ( percent * theta ) / sineTheta * inverted ; return a . mul ( coefficient1 ) . add ( b . mul ( coefficient2 ) ) ; }

Interpolates a quaternion between two others using spherical linear interpolation.

@param a The first quaternion
@param b The second quaternion
@param percent The percent for the interpolation, between 0 and 1 inclusively
@return The interpolated quaternion

Interpolates a quaternion between two others using spherical linear interpolation .


public static double biLerp(double x, double y, double q00, double q01,
                                double q10, double q11, double x1, double x2, double y1, double y2) {
        double q0 = lerp(x, x1, x2, q00, q10);
        double q1 = lerp(x, x1, x2, q01, q11);
        return lerp(y, y1, y2, q0, q1);
    }

public static double biLerp ( double x , double y , double q00 , double q01 , double q10 , double q11 , double x1 , double x2 , double y1 , double y2 ) { double q0 = lerp ( x , x1 , x2 , q00 , q10 ) ; double q1 = lerp ( x , x1 , x2 , q01 , q11 ) ; return lerp ( y , y1 , y2 , q0 , q1 ) ; }

Calculates the value at x,y using bilinear interpolation

@param x the X coord of the value to interpolate
@param y the Y coord of the value to interpolate
@param q00 the first known value (x1, y1)
@param q01 the second known value (x1, y2)
@param q10 the third known value (x2, y1)
@param q11 the fourth known value (x2, y2)
@param x1 the X coord of q00 and q01
@param x2 the X coord of q10 and q11
@param y1 the Y coord of q00 and q10
@param y2 the Y coord of q01 and q11
@return the interpolated value

Calculates the value at x y using bilinear interpolation


public static double triLerp(double x, double y, double z, double q000, double q001,
                                 double q010, double q011, double q100, double q101, double q110, double q111,
                                 double x1, double x2, double y1, double y2, double z1, double z2) {
        double q00 = lerp(x, x1, x2, q000, q100);
        double q01 = lerp(x, x1, x2, q010, q110);
        double q10 = lerp(x, x1, x2, q001, q101);
        double q11 = lerp(x, x1, x2, q011, q111);
        double q0 = lerp(y, y1, y2, q00, q10);
        double q1 = lerp(y, y1, y2, q01, q11);
        return lerp(z, z1, z2, q0, q1);
    }

public static double triLerp ( double x , double y , double z , double q000 , double q001 , double q010 , double q011 , double q100 , double q101 , double q110 , double q111 , double x1 , double x2 , double y1 , double y2 , double z1 , double z2 ) { double q00 = lerp ( x , x1 , x2 , q000 , q100 ) ; double q01 = lerp ( x , x1 , x2 , q010 , q110 ) ; double q10 = lerp ( x , x1 , x2 , q001 , q101 ) ; double q11 = lerp ( x , x1 , x2 , q011 , q111 ) ; double q0 = lerp ( y , y1 , y2 , q00 , q10 ) ; double q1 = lerp ( y , y1 , y2 , q01 , q11 ) ; return lerp ( z , z1 , z2 , q0 , q1 ) ; }

Calculates the value at x,y,z using trilinear interpolation

@param x the X coord of the value to interpolate
@param y the Y coord of the value to interpolate
@param z the Z coord of the value to interpolate
@param q000 the first known value (x1, y1, z1)
@param q001 the second known value (x1, y2, z1)
@param q010 the third known value (x1, y1, z2)
@param q011 the fourth known value (x1, y2, z2)
@param q100 the fifth known value (x2, y1, z1)
@param q101 the sixth known value (x2, y2, z1)
@param q110 the seventh known value (x2, y1, z2)
@param q111 the eighth known value (x2, y2, z2)
@param x1 the X coord of q000, q001, q010 and q011
@param x2 the X coord of q100, q101, q110 and q111
@param y1 the Y coord of q000, q010, q100 and q110
@param y2 the Y coord of q001, q011, q101 and q111
@param z1 the Z coord of q000, q001, q100 and q101
@param z2 the Z coord of q010, q011, q110 and q111
@return the interpolated value

Calculates the value at x y z using trilinear interpolation


public static Color blend(Color a, Color b) {
        return lerp(a, b, a.getAlpha() / 255f);
    }

public static Color blend ( Color a , Color b ) { return lerp ( a , b , a . getAlpha ( ) / 255f ) ; }

Blends two colors into one.

@param a The first color
@param b The second color
@return The blended color


public static double clamp(double value, double low, double high) {
        if (value < low) {
            return low;
        }
        if (value > high) {
            return high;
        }
        return value;
    }

public static double clamp ( double value , double low , double high ) { if ( value < low ) { return low ; } if ( value > high ) { return high ; } return value ; }

Clamps the value between the low and high boundaries

@param value The value to clamp
@param low The low bound of the clamp
@param high The high bound of the clamp
@return the clamped value


public static double inverseSqrt(double a) {
        final double halfA = 0.5d * a;
        a = Double.longBitsToDouble(0x5FE6EB50C7B537AAl - (Double.doubleToRawLongBits(a) >> 1));
        return a * (1.5d - halfA * a * a);
    }

public static double inverseSqrt ( double a ) { final double halfA = 0.5d * a ; a = Double . longBitsToDouble ( 0x5FE6EB50C7B537AA l - ( Double . doubleToRawLongBits ( a ) >> 1 ) ) ; return a * ( 1.5d - halfA * a * a ) ; }

Returns a fast estimate of the inverse square root of the value

@param a The value
@return The estimate of the inverse square root


public static Float castFloat(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).floatValue();
        }
        try {
            return Float.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Float castFloat ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . floatValue ( ) ; } try { return Float . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to a float. May return null.

@param o The object to attempt to cast
@return The object as a float

Casts a value to a float . May return null .


public static Byte castByte(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).byteValue();
        }
        try {
            return Byte.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Byte castByte ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . byteValue ( ) ; } try { return Byte . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to a byte. May return null.

@param o The object to attempt to cast
@return The object as a byte

Casts a value to a byte . May return null .


public static Short castShort(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).shortValue();
        }
        try {
            return Short.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Short castShort ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . shortValue ( ) ; } try { return Short . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to a short. May return null.

@param o The object to attempt to cast
@return The object as a short

Casts a value to a short . May return null .


public static Integer castInt(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).intValue();
        }
        try {
            return Integer.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Integer castInt ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . intValue ( ) ; } try { return Integer . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to an integer. May return null.

@param o The object to attempt to cast
@return The object as an int

Casts a value to an integer . May return null .


public static Double castDouble(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).doubleValue();
        }
        try {
            return Double.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Double castDouble ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . doubleValue ( ) ; } try { return Double . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to a double. May return null.

@param o The object to attempt to cast
@return The object as a double

Casts a value to a double . May return null .


public static Long castLong(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Number) {
            return ((Number) o).longValue();
        }
        try {
            return Long.valueOf(o.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

public static Long castLong ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Number ) { return ( ( Number ) o ) . longValue ( ) ; } try { return Long . valueOf ( o . toString ( ) ) ; } catch ( NumberFormatException e ) { return null ; } }

Casts a value to a long. May return null.

@param o The object to attempt to cast
@return The object as a long

Casts a value to a long . May return null .


public static Boolean castBoolean(Object o) {
        if (o == null) {
            return null;
        }
        if (o instanceof Boolean) {
            return (Boolean) o;
        } else if (o instanceof String) {
            try {
                return Boolean.parseBoolean((String) o);
            } catch (IllegalArgumentException e) {
                return null;
            }
        }

        return null;
    }

public static Boolean castBoolean ( Object o ) { if ( o == null ) { return null ; } if ( o instanceof Boolean ) { return ( Boolean ) o ; } else if ( o instanceof String ) { try { return Boolean . parseBoolean ( ( String ) o ) ; } catch ( IllegalArgumentException e ) { return null ; } } return null ; }

Casts a value to a boolean. May return null.

@param o The object to attempt to cast
@return The object as a boolean

Casts a value to a boolean . May return null .


public static int mean(int... values) {
        int sum = 0;
        for (int v : values) {
            sum += v;
        }
        return sum / values.length;
    }

public static int mean ( int ... values ) { int sum = 0 ; for ( int v : values ) { sum += v ; } return sum / values . length ; }

Calculates the mean of a set of values

@param values to calculate the mean of
@return the mean of the values


public static double mod(double a, double div) {
        final double remainder = a % div;
        return remainder < 0 ? remainder + div : remainder;
    }

public static double mod ( double a , double div ) { final double remainder = a % div ; return remainder < 0 ? remainder + div : remainder ; }

Returns the modulo of 'a' by 'div' with corrections for negative numbers.

@param a The dividend
@param div The divider
@return The corrected modulo

Returns the modulo of a by div with corrections for negative numbers .


public static int multiplyToShift(int a) {
        if (a < 1) {
            throw new IllegalArgumentException("Multiplicand must be at least 1");
        }
        int shift = 31 - Integer.numberOfLeadingZeros(a);
        if ((1 << shift) != a) {
            throw new IllegalArgumentException("Multiplicand must be a power of 2");
        }
        return shift;
    }

public
static
int
multiplyToShift
(
int
a
)
{
if
(
a
<
1
)
{
throw
new
IllegalArgumentException
(
"Multiplicand must be at least 1"
)
;
}
int
shift
=
31
Integer
.
numberOfLeadingZeros
(
a
)
;
if
(
(
1
<<
shift
)
!=
a
)
{
throw
new
IllegalArgumentException
(
"Multiplicand must be a power of 2"
)
;
}
return
shift
;
}

Converts a multiplication into a shift.

@param a the multiplicand
@return the left shift required to multiply by the multiplicand

Converts a multiplication into a shift .


@Override
    public Quaterniond mul(double a) {
        return new Quaterniond(x * a, y * a, z * a, w * a);
    }

@ Override public Quaterniond mul ( double a ) { return new Quaterniond ( x * a , y * a , z * a , w * a ) ; }

Multiplies the components of this quaternion by a double scalar.

@param a The multiplication scalar
@return A new quaternion, which has each component multiplied by the scalar

Multiplies the components of this quaternion by a double scalar .


@Override
    public Quaterniond div(double a) {
        return new Quaterniond(x / a, y / a, z / a, w / a);
    }

@ Override public Quaterniond div ( double a ) { return new Quaterniond ( x / a , y / a , z / a , w / a ) ; }

Divides the components of this quaternion by a double scalar.

@param a The division scalar
@return A new quaternion, which has each component divided by the scalar

Divides the components of this quaternion by a double scalar .


public Vector3d rotate(double x, double y, double z) {
        final double length = length();
        if (Math.abs(length) < GenericMath.DBL_EPSILON) {
            throw new ArithmeticException("Cannot rotate by the zero quaternion");
        }
        final double nx = this.x / length;
        final double ny = this.y / length;
        final double nz = this.z / length;
        final double nw = this.w / length;
        final double px = nw * x + ny * z - nz * y;
        final double py = nw * y + nz * x - nx * z;
        final double pz = nw * z + nx * y - ny * x;
        final double pw = -nx * x - ny * y - nz * z;
        return new Vector3d(
                pw * -nx + px * nw - py * nz + pz * ny,
                pw * -ny + py * nw - pz * nx + px * nz,
                pw * -nz + pz * nw - px * ny + py * nx);
    }

public
Vector3d
rotate
(
double
x
,
double
y
,
double
z
)
{
final
double
length
=
length
(
)
;
if
(
Math
.
abs
(
length
)
<
GenericMath
.
DBL_EPSILON
)
{
throw
new
ArithmeticException
(
"Cannot rotate by the zero quaternion"
)
;
}
final
double
nx
=
this
.
x
/
length
;
final
double
ny
=
this
.
y
/
length
;
final
double
nz
=
this
.
z
/
length
;
final
double
nw
=
this
.
w
/
length
;
final
double
px
=
nw
*
x
+
ny
*
z
nz
*
y
;
final
double
py
=
nw
*
y
+
nz
*
x
nx
*
z
;
final
double
pz
=
nw
*
z
+
nx
*
y
ny
*
x
;
final
double
pw
=
nx
*
x
ny
*
y
nz
*
z
;
return
new
Vector3d
(
pw
*
nx
+
px
*
nw
py
*
nz
+
pz
*
ny
,
pw
*
ny
+
py
*
nw
pz
*
nx
+
px
*
nz
,
pw
*
nz
+
pz
*
nw
px
*
ny
+
py
*
nx
)
;
}

Rotates the double components of a vector by this quaternion.

@param x The x component of the vector
@param y The y component of the vector
@param z The z component of the vector
@return The rotated vector

Rotates the double components of a vector by this quaternion .


@Override
    public double lengthSquared() {
        return x * x + y * y + z * z + w * w;
    }

@ Override public double lengthSquared ( ) { return x * x + y * y + z * z + w * w ; }

Returns the square of the length of this quaternion.

@return The square of the length

Returns the square of the length of this quaternion .


@Override
    public Quaterniond normalize() {
        final double length = length();
        if (Math.abs(length) < GenericMath.DBL_EPSILON) {
            throw new ArithmeticException("Cannot normalize the zero quaternion");
        }
        return new Quaterniond(x / length, y / length, z / length, w / length);
    }

@
Override
public
Quaterniond
normalize
(
)
{
final
double
length
=
length
(
)
;
if
(
Math
.
abs
(
length
)
<
GenericMath
.
DBL_EPSILON
)
{
throw
new
ArithmeticException
(
"Cannot normalize the zero quaternion"
)
;
}
return
new
Quaterniond
(
x
/
length
,
y
/
length
,
z
/
length
,
w
/
length
)
;
}

Normalizes this quaternion.

@return A new quaternion of unit length


public static Quaterniond fromImaginary(double x, double y, double z) {
         return x == 0 && y == 0 && z == 0 ? ZERO : new Quaterniond(x, y, z, 0);
    }

public static Quaterniond fromImaginary ( double x , double y , double z ) { return x == 0 && y == 0 && z == 0 ? ZERO : new Quaterniond ( x , y , z , 0 ) ; }

Creates a new quaternion from the double imaginary components.

The {@link #ZERO} constant is re-used when {@code x}, {@code y}, and {@code z} are 0.

@param x The x (imaginary) component
@param y The y (imaginary) component
@param z The z (imaginary) component
@return The quaternion created from the double imaginary components

Creates a new quaternion from the double imaginary components .


public static Quaterniond from(double x, double y, double z, double w) {
         return x == 0 && y == 0 && z == 0 && w == 0 ? ZERO : new Quaterniond(x, y, z, w);
    }

public static Quaterniond from ( double x , double y , double z , double w ) { return x == 0 && y == 0 && z == 0 && w == 0 ? ZERO : new Quaterniond ( x , y , z , w ) ; }

Creates a new quaternion from the double components.

The {@link #ZERO} constant is re-used when {@code x}, {@code y}, {@code z}, and {@code w} are 0.

@param x The x (imaginary) component
@param y The y (imaginary) component
@param z The z (imaginary) component
@param w The w (real) component
@return The quaternion created from the double components

Creates a new quaternion from the double components .


public static Quaterniond fromAxesAnglesDeg(double pitch, double yaw, double roll) {
        return Quaterniond.fromAngleDegAxis(yaw, Vector3d.UNIT_Y).
                mul(Quaterniond.fromAngleDegAxis(pitch, Vector3d.UNIT_X)).
                mul(Quaterniond.fromAngleDegAxis(roll, Vector3d.UNIT_Z));
    }

public static Quaterniond fromAxesAnglesDeg ( double pitch , double yaw , double roll ) { return Quaterniond . fromAngleDegAxis ( yaw , Vector3d . UNIT_Y ) . mul ( Quaterniond . fromAngleDegAxis ( pitch , Vector3d . UNIT_X ) ) . mul ( Quaterniond . fromAngleDegAxis ( roll , Vector3d . UNIT_Z ) ) ; }

Creates a new quaternion from the double angles in degrees around the x, y and z axes.

@param pitch The rotation around x
@param yaw The rotation around y
@param roll The rotation around z
@return The quaternion defined by the rotations around the axes

Creates a new quaternion from the double angles in degrees around the x y and z axes .


public static Quaterniond fromAxesAnglesRad(double pitch, double yaw, double roll) {
        return Quaterniond.fromAngleRadAxis(yaw, Vector3d.UNIT_Y).
                mul(Quaterniond.fromAngleRadAxis(pitch, Vector3d.UNIT_X)).
                mul(Quaterniond.fromAngleRadAxis(roll, Vector3d.UNIT_Z));
    }

public static Quaterniond fromAxesAnglesRad ( double pitch , double yaw , double roll ) { return Quaterniond . fromAngleRadAxis ( yaw , Vector3d . UNIT_Y ) . mul ( Quaterniond . fromAngleRadAxis ( pitch , Vector3d . UNIT_X ) ) . mul ( Quaterniond . fromAngleRadAxis ( roll , Vector3d . UNIT_Z ) ) ; }

Creates a new quaternion from the double angles in radians around the x, y and z axes.

@param pitch The rotation around x
@param yaw The rotation around y
@param roll The rotation around z
@return The quaternion defined by the rotations around the axes

Creates a new quaternion from the double angles in radians around the x y and z axes .


public static Quaterniond fromAngleRadAxis(double angle, Vector3d axis) {
        return fromAngleRadAxis(angle, axis.getX(), axis.getY(), axis.getZ());
    }

public static Quaterniond fromAngleRadAxis ( double angle , Vector3d axis ) { return fromAngleRadAxis ( angle , axis . getX ( ) , axis . getY ( ) , axis . getZ ( ) ) ; }

Creates a new quaternion from the rotation double angle in radians around the axis vector.

@param angle The rotation angle in radians
@param axis The axis of rotation
@return The quaternion defined by the rotation around the axis

Creates a new quaternion from the rotation double angle in radians around the axis vector .


public static Quaterniond fromAngleDegAxis(float angle, float x, float y, float z) {
        return fromAngleRadAxis(Math.toRadians(angle), x, y, z);
    }

public static Quaterniond fromAngleDegAxis ( float angle , float x , float y , float z ) { return fromAngleRadAxis ( Math . toRadians ( angle ) , x , y , z ) ; }

Creates a new quaternion from the rotation float angle in degrees around the axis vector float components.

@param angle The rotation angle in degrees
@param x The x component of the axis vector
@param y The y component of the axis vector
@param z The z component of the axis vector
@return The quaternion defined by the rotation around the axis

Creates a new quaternion from the rotation float angle in degrees around the axis vector float components .


@Override
    public int getMinAxis() {
        int value = x;
        int axis = 0;
        if (y < value) {
            value = y;
            axis = 1;
        }
        if (z < value) {
            value = z;
            axis = 2;
        }
        if (w < value) {
            axis = 3;
        }
        return axis;
    }

@ Override public int getMinAxis ( ) { int value = x ; int axis = 0 ; if ( y < value ) { value = y ; axis = 1 ; } if ( z < value ) { value = z ; axis = 2 ; } if ( w < value ) { axis = 3 ; } return axis ; }

Return the axis with the minimal value.

@return {@link int} axis with minimal value

Return the axis with the minimal value .


public Complexf mul(float x, float y) {
        return new Complexf(
                this.x * x - this.y * y,
                this.x * y + this.y * x);
    }

public Complexf mul ( float x , float y ) { return new Complexf ( this . x * x - this . y * y , this . x * y + this . y * x ) ; }

Multiplies the float components of another complex with this one.

@param x The x (real) component of the complex to multiply with
@param y The y (imaginary) component of the complex to multiply with
@return A new complex, which is the product of both

Multiplies the float components of another complex with this one .


public Complexf div(float x, float y) {
        final float d = x * x + y * y;
        return new Complexf(
                (this.x * x + this.y * y) / d,
                (this.y * x - this.x * y) / d);
    }

public Complexf div ( float x , float y ) { final float d = x * x + y * y ; return new Complexf ( ( this . x * x + this . y * y ) / d , ( this . y * x - this . x * y ) / d ) ; }

Divides this complex by the float components of another one.

@param x The x (real) component of the complex to divide with
@param y The y (imaginary) component of the complex to divide with
@return The quotient of the two complexes

Divides this complex by the float components of another one .


public Vector2f rotate(float x, float y) {
        final float length = length();
        if (Math.abs(length) < GenericMath.FLT_EPSILON) {
            throw new ArithmeticException("Cannot rotate by the zero complex");
        }
        final float nx = this.x / length;
        final float ny = this.y / length;
        return new Vector2f(x * nx - y * ny, y * nx + x * ny);
    }

public
Vector2f
rotate
(
float
x
,
float
y
)
{
final
float
length
=
length
(
)
;
if
(
Math
.
abs
(
length
)
<
GenericMath
.
FLT_EPSILON
)
{
throw
new
ArithmeticException
(
"Cannot rotate by the zero complex"
)
;
}
final
float
nx
=
this
.
x
/
length
;
final
float
ny
=
this
.
y
/
length
;
return
new
Vector2f
(
x
*
nx
y
*
ny
,
y
*
nx
+
x
*
ny
)
;
}

Rotates the float components of a vector by this complex.

@param x The x component of the vector
@param y The y component of the vector
@return The rotated vector

Rotates the float components of a vector by this complex .


@Override
    public Complexf normalize() {
        final float length = length();
        if (Math.abs(length) < GenericMath.FLT_EPSILON) {
            throw new ArithmeticException("Cannot normalize the zero complex");
        }
        return new Complexf(x / length, y / length);
    }

@
Override
public
Complexf
normalize
(
)
{
final
float
length
=
length
(
)
;
if
(
Math
.
abs
(
length
)
<
GenericMath
.
FLT_EPSILON
)
{
throw
new
ArithmeticException
(
"Cannot normalize the zero complex"
)
;
}
return
new
Complexf
(
x
/
length
,
y
/
length
)
;
}

Normalizes this complex.

@return A new complex of unit length


public Quaternionf toQuaternion(float x, float y, float z) {
        return Quaternionf.fromAngleRadAxis(getAngleRad(), x, y, z);
    }

public Quaternionf toQuaternion ( float x , float y , float z ) { return Quaternionf . fromAngleRadAxis ( getAngleRad ( ) , x , y , z ) ; }

Converts this complex to a quaternion by
using the provided float components vector
as a rotation axis.

@param x The x component of the axis vector
@param y The y component of the axis vector
@param z The z component of the axis vector
@return A quaternion of this rotation around the given axis

Converts this complex to a quaternion by using the provided float components vector as a rotation axis .


public static Complexf from(float x, float y) {
         return x == 0 && y == 0 ? ZERO : new Complexf(x, y);
    }

public static Complexf from ( float x , float y ) { return x == 0 && y == 0 ? ZERO : new Complexf ( x , y ) ; }

Creates a new complex from the float components.

The {@link #ZERO} constant is re-used when both {@code x} and {@code z} are 0.

@param x The x (real) component
@param y The y (imaginary) component
@return The complex created from the float components

Creates a new complex from the float components .


public static Complexf fromAngleRad(float angle) {
        return new Complexf(TrigMath.cos(angle), TrigMath.sin(angle));
    }

public static Complexf fromAngleRad ( float angle ) { return new Complexf ( TrigMath . cos ( angle ) , TrigMath . sin ( angle ) ) ; }

Creates a new complex from the float angle in radians.

@param angle The angle in radians
@return The complex defined by the angle

Creates a new complex from the float angle in radians .


@Override
    public int getMaxAxis() {
        long value = x;
        int axis = 0;
        if (y > value) {
            value = y;
            axis = 1;
        }
        if (z > value) {
            value = z;
            axis = 2;
        }
        if (w > value) {
            axis = 3;
        }
        return axis;
    }

@ Override public int getMaxAxis ( ) { long value = x ; int axis = 0 ; if ( y > value ) { value = y ; axis = 1 ; } if ( z > value ) { value = z ; axis = 2 ; } if ( w > value ) { axis = 3 ; } return axis ; }

Return the axis with the maximum value.

@return {@link int} axis with maximum value

Return the axis with the maximum value .


public static int hash(double value) {
        assert !Double.isNaN(value) : "Values of NaN are not supported.";

        long bits = Double.doubleToLongBits(value);
        return (int) (bits ^ (bits >>> 32));
        //return (int) Double.doubleToLongBits(value*663608941.737);
        // This avoids excessive hashCollisions in the case values are of the form (1.0, 2.0, 3.0, ...)
    }

Returns a hashcode for the specified value.

@return a hash code value for the specified value.

Returns a hashcode for the specified value .


public Quaternionf add(float x, float y, float z, float w) {
        return new Quaternionf(this.x + x, this.y + y, this.z + z, this.w + w);
    }

public Quaternionf add ( float x , float y , float z , float w ) { return new Quaternionf ( this . x + x , this . y + y , this . z + z , this . w + w ) ; }

Adds the float components of another quaternion to this one.

@param x The x (imaginary) component of the quaternion to add
@param y The y (imaginary) component of the quaternion to add
@param z The z (imaginary) component of the quaternion to add
@param w The w (real) component of the quaternion to add
@return A new quaternion, which is the sum of both

Adds the float components of another quaternion to this one .


@Override
    public Quaternionf mul(float a) {
        return new Quaternionf(x * a, y * a, z * a, w * a);
    }

@ Override public Quaternionf mul ( float a ) { return new Quaternionf ( x * a , y * a , z * a , w * a ) ; }

Multiplies the components of this quaternion by a float scalar.

@param a The multiplication scalar
@return A new quaternion, which has each component multiplied by the scalar

Multiplies the components of this quaternion by a float scalar .


@Override
    public Quaternionf div(float a) {
        return new Quaternionf(x / a, y / a, z / a, w / a);
    }

@ Override public Quaternionf div ( float a ) { return new Quaternionf ( x / a , y / a , z / a , w / a ) ; }

Divides the components of this quaternion by a float scalar.

@param a The division scalar
@return A new quaternion, which has each component divided by the scalar

Divides the components of this quaternion by a float scalar .


public Vector3f getAxis() {
        final float q = (float) Math.sqrt(1 - w * w);
        return new Vector3f(x / q, y / q, z / q);
    }

public Vector3f getAxis ( ) { final float q = ( float ) Math . sqrt ( 1 - w * w ) ; return new Vector3f ( x / q , y / q , z / q ) ; }

Returns the axis of rotation for this quaternion.

@return The axis of rotation

Returns the axis of rotation for this quaternion .


public Vector3f getAxesAnglesRad() {
        final double roll;
        final double pitch;
        double yaw;
        final double test = w * x - y * z;
        if (Math.abs(test) < 0.4999) {
            roll = TrigMath.atan2(2 * (w * z + x * y), 1 - 2 * (x * x + z * z));
            pitch = TrigMath.asin(2 * test);
            yaw = TrigMath.atan2(2 * (w * y + z * x), 1 - 2 * (x * x + y * y));
        } else {
            final int sign = (test < 0) ? -1 : 1;
            roll = 0;
            pitch = sign * Math.PI / 2;
            yaw = -sign * 2 * TrigMath.atan2(z, w);
        }
        return new Vector3f(pitch, yaw, roll);
    }

public Vector3f getAxesAnglesRad ( ) { final double roll ; final double pitch ; double yaw ; final double test = w * x - y * z ; if ( Math . abs ( test ) < 0.4999 ) { roll = TrigMath . atan2 ( 2 * ( w * z + x * y ) , 1 - 2 * ( x * x + z * z ) ) ; pitch = TrigMath . asin ( 2 * test ) ; yaw = TrigMath . atan2 ( 2 * ( w * y + z * x ) , 1 - 2 * ( x * x + y * y ) ) ; } else { final int sign = ( test < 0 ) ? - 1 : 1 ; roll = 0 ; pitch = sign * Math . PI / 2 ; yaw = - sign * 2 * TrigMath . atan2 ( z , w ) ; } return new Vector3f ( pitch , yaw , roll ) ; }

Returns the angles in radians around the x, y and z axes that correspond to the rotation represented by this quaternion.

@return The angle in radians for each axis, stored in a vector, in the corresponding component

Returns the angles in radians around the x y and z axes that correspond to the rotation represented by this quaternion .


public static Quaternionf fromImaginary(float x, float y, float z) {
         return x == 0 && y == 0 && z == 0 ? ZERO : new Quaternionf(x, y, z, 0);
    }

public static Quaternionf fromImaginary ( float x , float y , float z ) { return x == 0 && y == 0 && z == 0 ? ZERO : new Quaternionf ( x , y , z , 0 ) ; }

Creates a new quaternion from the float imaginary components.

The {@link #ZERO} constant is re-used when {@code x}, {@code y}, and {@code z} are 0.

@param x The x (imaginary) component
@param y The y (imaginary) component
@param z The z (imaginary) component
@return The quaternion created from the float imaginary components

Creates a new quaternion from the float imaginary components .


public static Quaternionf from(float x, float y, float z, float w) {
         return x == 0 && y == 0 && z == 0 && w == 0 ? ZERO : new Quaternionf(x, y, z, w);
    }

public static Quaternionf from ( float x , float y , float z , float w ) { return x == 0 && y == 0 && z == 0 && w == 0 ? ZERO : new Quaternionf ( x , y , z , w ) ; }

Creates a new quaternion from the float components.

The {@link #ZERO} constant is re-used when {@code x}, {@code y}, {@code z}, and {@code w} are 0.

@param x The x (imaginary) component
@param y The y (imaginary) component
@param z The z (imaginary) component
@param w The w (real) component
@return The quaternion created from the float components

Creates a new quaternion from the float components .


public static Quaternionf fromAxesAnglesDeg(float pitch, float yaw, float roll) {
        return Quaternionf.fromAngleDegAxis(yaw, Vector3f.UNIT_Y).
                mul(Quaternionf.fromAngleDegAxis(pitch, Vector3f.UNIT_X)).
                mul(Quaternionf.fromAngleDegAxis(roll, Vector3f.UNIT_Z));
    }

public static Quaternionf fromAxesAnglesDeg ( float pitch , float yaw , float roll ) { return Quaternionf . fromAngleDegAxis ( yaw , Vector3f . UNIT_Y ) . mul ( Quaternionf . fromAngleDegAxis ( pitch , Vector3f . UNIT_X ) ) . mul ( Quaternionf . fromAngleDegAxis ( roll , Vector3f . UNIT_Z ) ) ; }

Creates a new quaternion from the float angles in degrees around the x, y and z axes.

@param pitch The rotation around x
@param yaw The rotation around y
@param roll The rotation around z
@return The quaternion defined by the rotations around the axes

Creates a new quaternion from the float angles in degrees around the x y and z axes .


public static Quaternionf fromAxesAnglesRad(float pitch, float yaw, float roll) {
        return Quaternionf.fromAngleRadAxis(yaw, Vector3f.UNIT_Y).
                mul(Quaternionf.fromAngleRadAxis(pitch, Vector3f.UNIT_X)).
                mul(Quaternionf.fromAngleRadAxis(roll, Vector3f.UNIT_Z));
    }

public static Quaternionf fromAxesAnglesRad ( float pitch , float yaw , float roll ) { return Quaternionf . fromAngleRadAxis ( yaw , Vector3f . UNIT_Y ) . mul ( Quaternionf . fromAngleRadAxis ( pitch , Vector3f . UNIT_X ) ) . mul ( Quaternionf . fromAngleRadAxis ( roll , Vector3f . UNIT_Z ) ) ; }

Creates a new quaternion from the float angles in radians around the x, y and z axes.

@param pitch The rotation around x
@param yaw The rotation around y
@param roll The rotation around z
@return The quaternion defined by the rotations around the axes

Creates a new quaternion from the float angles in radians around the x y and z axes .


public static Quaternionf fromAngleRadAxis(float angle, Vector3f axis) {
        return fromAngleRadAxis(angle, axis.getX(), axis.getY(), axis.getZ());
    }

public static Quaternionf fromAngleRadAxis ( float angle , Vector3f axis ) { return fromAngleRadAxis ( angle , axis . getX ( ) , axis . getY ( ) , axis . getZ ( ) ) ; }

Creates a new quaternion from the rotation float angle in radians around the axis vector.

@param angle The rotation angle in radians
@param axis The axis of rotation
@return The quaternion defined by the rotation around the axis

Creates a new quaternion from the rotation float angle in radians around the axis vector .


public static Quaternionf fromAngleRadAxis(double angle, double x, double y, double z) {
        return fromAngleRadAxis((float) angle, (float) x, (float) y, (float) z);
    }

public static Quaternionf fromAngleRadAxis ( double angle , double x , double y , double z ) { return fromAngleRadAxis ( ( float ) angle , ( float ) x , ( float ) y , ( float ) z ) ; }

Creates a new quaternion from the rotation double angle in radians around the axis vector double components.

@param angle The rotation angle in radians
@param x The x component of the axis vector
@param y The y component of the axis vector
@param z The z component of the axis vector
@return The quaternion defined by the rotation around the axis

Creates a new quaternion from the rotation double angle in radians around the axis vector double components .


public Complexd mul(double x, double y) {
        return new Complexd(
                this.x * x - this.y * y,
                this.x * y + this.y * x);
    }

public Complexd mul ( double x , double y ) { return new Complexd ( this . x * x - this . y * y , this . x * y + this . y * x ) ; }

Multiplies the double components of another complex with this one.

@param x The x (real) component of the complex to multiply with
@param y The y (imaginary) component of the complex to multiply with
@return A new complex, which is the product of both

Multiplies the double components of another complex with this one .


public Complexd div(double x, double y) {
        final double d = x * x + y * y;
        return new Complexd(
                (this.x * x + this.y * y) / d,
                (this.y * x - this.x * y) / d);
    }

public Complexd div ( double x , double y ) { final double d = x * x + y * y ; return new Complexd ( ( this . x * x + this . y * y ) / d , ( this . y * x - this . x * y ) / d ) ; }

Divides this complex by the double components of another one.

@param x The x (real) component of the complex to divide with
@param y The y (imaginary) component of the complex to divide with
@return The quotient of the two complexes

Divides this complex by the double components of another one .


public Vector2d rotate(double x, double y) {
        final double length = length();
        if (Math.abs(length) < GenericMath.DBL_EPSILON) {
            throw new ArithmeticException("Cannot rotate by the zero complex");
        }
        final double nx = this.x / length;
        final double ny = this.y / length;
        return new Vector2d(x * nx - y * ny, y * nx + x * ny);
    }

public
Vector2d
rotate
(
double
x
,
double
y
)
{
final
double
length
=
length
(
)
;
if
(
Math
.
abs
(
length
)
<
GenericMath
.
DBL_EPSILON
)
{
throw
new
ArithmeticException
(
"Cannot rotate by the zero complex"
)
;
}
final
double
nx
=
this
.
x
/
length
;
final
double
ny
=
this
.
y
/
length
;
return
new
Vector2d
(
x
*
nx
y
*
ny
,
y
*
nx
+
x
*
ny
)
;
}

Rotates the double components of a vector by this complex.

@param x The x component of the vector
@param y The y component of the vector
@return The rotated vector

Rotates the double components of a vector by this complex .


public Quaterniond toQuaternion(double x, double y, double z) {
        return Quaterniond.fromAngleRadAxis(getAngleRad(), x, y, z);
    }

public Quaterniond toQuaternion ( double x , double y , double z ) { return Quaterniond . fromAngleRadAxis ( getAngleRad ( ) , x , y , z ) ; }

Converts this complex to a quaternion by
using the provided double components vector
as a rotation axis.

@param x The x component of the axis vector
@param y The y component of the axis vector
@param z The z component of the axis vector
@return A quaternion of this rotation around the given axis

Converts this complex to a quaternion by using the provided double components vector as a rotation axis .


public static Complexd from(double x, double y) {
         return x == 0 && y == 0 ? ZERO : new Complexd(x, y);
    }

public static Complexd from ( double x , double y ) { return x == 0 && y == 0 ? ZERO : new Complexd ( x , y ) ; }

Creates a new complex from the double components.

The {@link #ZERO} constant is re-used when both {@code x} and {@code z} are 0.

@param x The x (real) component
@param y The y (imaginary) component
@return The complex created from the double components

Creates a new complex from the double components .


public static Complexd fromAngleRad(double angle) {
        return new Complexd(TrigMath.cos(angle), TrigMath.sin(angle));
    }

public static Complexd fromAngleRad ( double angle ) { return new Complexd ( TrigMath . cos ( angle ) , TrigMath . sin ( angle ) ) ; }

Creates a new complex from the double angle in radians.

@param angle The angle in radians
@return The complex defined by the angle

Creates a new complex from the double angle in radians .


public void moveChildView(View pChildView, float pScale_Left, float pScale_Top) {
        ScalableLayout.LayoutParams lSLLP = getChildLayoutParams(pChildView);
        lSLLP.mScale_Left = pScale_Left;
        lSLLP.mScale_Top = pScale_Top;
        postInvalidate();
    }

public void moveChildView ( View pChildView , float pScale_Left , float pScale_Top ) { ScalableLayout . LayoutParams lSLLP = getChildLayoutParams ( pChildView ) ; lSLLP . mScale_Left = pScale_Left ; lSLLP . mScale_Top = pScale_Top ; postInvalidate ( ) ; }

move childView inside ScalableLayout
@param pChildView view to move. should be child of ScaleLayout
@param pScale_Left
@param pScale_Top


public void moveChildView(View pChildView, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
        ScalableLayout.LayoutParams lSLLP = getChildLayoutParams(pChildView);
        lSLLP.mScale_Left = pScale_Left;
        lSLLP.mScale_Top = pScale_Top;
        lSLLP.mScale_Width = pScale_Width;
        lSLLP.mScale_Height = pScale_Height;
        postInvalidate();
    }

public void moveChildView ( View pChildView , float pScale_Left , float pScale_Top , float pScale_Width , float pScale_Height ) { ScalableLayout . LayoutParams lSLLP = getChildLayoutParams ( pChildView ) ; lSLLP . mScale_Left = pScale_Left ; lSLLP . mScale_Top = pScale_Top ; lSLLP . mScale_Width = pScale_Width ; lSLLP . mScale_Height = pScale_Height ; postInvalidate ( ) ; }

move and resize childView inside ScalableLayout
@param pChildView view to move. should be child of ScaleLayout
@param pScale_Left
@param pScale_Top
@param pScale_Width
@param pScale_Height


private static void setBlockSpan(SpannableStringBuilder builder, Object what) {
		int length = Math.max(0, builder.length() - 1);
		builder.setSpan(what, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
	}

private static void setBlockSpan ( SpannableStringBuilder builder , Object what ) { int length = Math . max ( 0 , builder . length ( ) - 1 ) ; builder . setSpan ( what , 0 , length , Spannable . SPAN_EXCLUSIVE_EXCLUSIVE ) ; }

These have trailing newlines that we want to avoid spanning


public BoundSet reduce(TypeSolver typeSolver) {
        List<ConstraintFormula> constraints = new LinkedList<>(constraintFormulas);
        BoundSet boundSet = BoundSet.empty();
        while (constraints.size() > 0) {
            ConstraintFormula constraintFormula = constraints.remove(0);
            ConstraintFormula.ReductionResult reductionResult = constraintFormula.reduce(boundSet);
            constraints.addAll(reductionResult.getConstraintFormulas());
            boundSet.incorporate(reductionResult.getBoundSet(), typeSolver);
        }
        return boundSet;
    }

public BoundSet reduce ( TypeSolver typeSolver ) { List < ConstraintFormula > constraints = new LinkedList <> ( constraintFormulas ) ; BoundSet boundSet = BoundSet . empty ( ) ; while ( constraints . size ( ) > 0 ) { ConstraintFormula constraintFormula = constraints . remove ( 0 ) ; ConstraintFormula . ReductionResult reductionResult = constraintFormula . reduce ( boundSet ) ; constraints . addAll ( reductionResult . getConstraintFormulas ( ) ) ; boundSet . incorporate ( reductionResult . getBoundSet ( ) , typeSolver ) ; } return boundSet ; }

Takes a compatibility assertion about an expression or type, called a constraint formula, and reduces it to a
set of bounds on inference variables. Often, a constraint formula reduces to other constraint formulas,
which must be recursively reduced. A procedure is followed to identify these additional constraint formulas and,
ultimately, to express via a bound set the conditions under which the choices for inferred types would render
each constraint formula true.

Takes a compatibility assertion about an expression or type called a constraint formula and reduces it to a set of bounds on inference variables . Often a constraint formula reduces to other constraint formulas which must be recursively reduced . A procedure is followed to identify these additional constraint formulas and ultimately to express via a bound set the conditions under which the choices for inferred types would render each constraint formula true .


@Override
    public ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer) {
        ResolvedType result = this;
        int i = 0;
        for (ResolvedType tp : this.typeParametersValues()) {
            ResolvedType transformedTp = transformer.transform(tp);
            // Identity comparison on purpose
            if (transformedTp != tp) {
                List<ResolvedType> typeParametersCorrected = result.asReferenceType().typeParametersValues();
                typeParametersCorrected.set(i, transformedTp);
                result = create(typeDeclaration, typeParametersCorrected);
            }
            i++;
        }
        return result;
    }

@
Override
public
ResolvedType
transformTypeParameters
(
ResolvedTypeTransformer
transformer
)
{
ResolvedType
result
=
this
;
int
i
=
0
;
for
(
ResolvedType
tp
:
this
.
typeParametersValues
(
)
)
{
ResolvedType
transformedTp
=
transformer
.
transform
(
tp
)
;
// Identity comparison on purpose
if
(
transformedTp
!=
tp
)
{
List
<
ResolvedType
>
typeParametersCorrected
=
result
.
asReferenceType
(
)
.
typeParametersValues
(
)
;
typeParametersCorrected
.
set
(
i
,
transformedTp
)
;
result
=
create
(
typeDeclaration
,
typeParametersCorrected
)
;
}
i
++
;
}
return
result
;
}

Execute a transformation on all the type parameters of this element.

Execute a transformation on all the type parameters of this element .


public static <S extends ResolvedDeclaration, S2 extends S> SymbolReference<S> solved(S2 symbolDeclaration) {
        return new SymbolReference<S>(Optional.of(symbolDeclaration));
    }

public static < S extends ResolvedDeclaration , S2 extends S > SymbolReference < S > solved ( S2 symbolDeclaration ) { return new SymbolReference < S > ( Optional . of ( symbolDeclaration ) ) ; }

Create a solve reference to the given symbol.

Create a solve reference to the given symbol .


public static <S extends ResolvedDeclaration, S2 extends S> SymbolReference<S> unsolved(Class<S2> clazz) {
        return new SymbolReference<>(Optional.empty());
    }

public static < S extends ResolvedDeclaration , S2 extends S > SymbolReference < S > unsolved ( Class < S2 > clazz ) { return new SymbolReference <> ( Optional . empty ( ) ) ; }

Create an unsolved reference specifying the type of the value expected.

Create an unsolved reference specifying the type of the value expected .


public static boolean isProperType(ResolvedType type) {
        if (type instanceof InferenceVariable) {
            return false;
        }
        if (type instanceof ResolvedReferenceType) {
            ResolvedReferenceType referenceType = (ResolvedReferenceType) type;
            return referenceType.typeParametersValues().stream().allMatch(it -> isProperType(it));
        }
        if (type instanceof ResolvedWildcard) {
            ResolvedWildcard wildcard = (ResolvedWildcard)type;
            if (wildcard.isBounded()) {
                return isProperType(wildcard.getBoundedType());
            } else {
                return true;
            }
        }
        if (type.isPrimitive()) {
            return true;
        }
        if (type.isTypeVariable()) {
            // FIXME I am not sure...
            return false;
        }
        if (type.isArray()) {
            return isProperType(type.asArrayType().getComponentType());
        }
        throw new UnsupportedOperationException(type.toString());
    }

public
static
boolean
isProperType
(
ResolvedType
type
)
{
if
(
type
instanceof
InferenceVariable
)
{
return
false
;
}
if
(
type
instanceof
ResolvedReferenceType
)
{
ResolvedReferenceType
referenceType
=
(
ResolvedReferenceType
)
type
;
return
referenceType
.
typeParametersValues
(
)
.
stream
(
)
.
allMatch
(
it
->
isProperType
(
it
)
)
;
}
if
(
type
instanceof
ResolvedWildcard
)
{
ResolvedWildcard
wildcard
=
(
ResolvedWildcard
)
type
;
if
(
wildcard
.
isBounded
(
)
)
{
return
isProperType
(
wildcard
.
getBoundedType
(
)
)
;
}
else
{
return
true
;
}
}
if
(
type
.
isPrimitive
(
)
)
{
return
true
;
}
if
(
type
.
isTypeVariable
(
)
)
{
// FIXME I am not sure...
return
false
;
}
if
(
type
.
isArray
(
)
)
{
return
isProperType
(
type
.
asArrayType
(
)
.
getComponentType
(
)
)
;
}
throw
new
UnsupportedOperationException
(
type
.
toString
(
)
)
;
}

The term proper type excludes such "types" that mention inference variables.

The term proper type excludes such types that mention inference variables .