text:
package com.google.javascript.rhino;

import com.google.javascript.rhino.Node.NodeMismatch;
import com.google.javascript.rhino.jstype.JSTypeNative;
import com.google.javascript.rhino.jstype.JSTypeRegistry;
import com.google.javascript.rhino.testing.TestErrorReporter;

import junit.framework.TestCase;

public class NodeTest extends TestCase {
  public void testMergeExtractNormal() throws Exception {
    testMergeExtract(5, 6);
    testMergeExtract(456, 3423);
    testMergeExtract(0, 0);
  }

  public void testMergeExtractErroneous() throws Exception {
    assertEquals(-1, Node.mergeLineCharNo(-5, 90));
    assertEquals(-1, Node.mergeLineCharNo(0, -1));
    assertEquals(-1, Node.extractLineno(-1));
    assertEquals(-1, Node.extractCharno(-1));
  }

  public void testMergeOverflowGraciously() throws Exception {
    int linecharno = Node.mergeLineCharNo(89, 4096);
    assertEquals(89, Node.extractLineno(linecharno));
    assertEquals(4095, Node.extractCharno(linecharno));
  }

  public void testCheckTreeEqualsImplSame() {
    Node node1 = new Node(1, new Node(2));
    Node node2 = new Node(1, new Node(2));
    assertEquals(null, node1.checkTreeEqualsImpl(node2));
  }

  public void testCheckTreeEqualsImplDifferentType() {
    Node node1 = new Node(1, new Node(2));
    Node node2 = new Node(2, new Node(2));
    assertEquals(new NodeMismatch(node1, node2),
        node1.checkTreeEqualsImpl(node2));
  }

  public void testCheckTreeEqualsImplDifferentChildCount() {
    Node node1 = new Node(1, new Node(2));
    Node node2 = new Node(1);
    assertEquals(new NodeMismatch(node1, node2),
        node1.checkTreeEqualsImpl(node2));
  }

  public void testCheckTreeEqualsImplDifferentChild() {
    Node child1 = new Node(1);
    Node child2 = new Node(2);
    Node node1 = new Node(1, child1);
    Node node2 = new Node(1, child2);
    assertEquals(new NodeMismatch(child1, child2),
        node1.checkTreeEqualsImpl(node2));
  }

  public void testCheckTreeEqualsSame() {
    Node node1 = new Node(1);
    assertEquals(null, node1.checkTreeEquals(node1));
  }

  public void testCheckTreeEqualsStringDifferent() {
    Node node1 = new Node(1);
    Node node2 = new Node(2);
    assertNotNull(node1.checkTreeEquals(node2));
  }

  public void testCheckTreeEqualsBooleanSame() {
    Node node1 = new Node(1);
    assertEquals(true, node1.isEquivalentTo(node1));
  }

  public void testCheckTreeEqualsBooleanDifferent() {
    Node node1 = new Node(1);
    Node node2 = new Node(2);
    assertEquals(false, node1.isEquivalentTo(node2));
  }

  public void testCheckTreeEqualsImplDifferentIncProp() {
    Node node1 = new Node(Token.INC);
    node1.putIntProp(Node.INCRDECR_PROP, 1);
    Node node2 = new Node(Token.INC);
    assertNotNull(node1.checkTreeEqualsImpl(node2));
  }

  public void testCheckTreeTypeAwareEqualsSame() {
    TestErrorReporter testErrorReporter = new TestErrorReporter(null, null);
    JSTypeRegistry registry = new JSTypeRegistry(testErrorReporter);
    Node node1 = Node.newString(Token.NAME, "f");
    node1.setJSType(registry.getNativeType(JSTypeNative.NUMBER_TYPE));
    Node node2 = Node.newString(Token.NAME, "f");
    node2.setJSType(registry.getNativeType(JSTypeNative.NUMBER_TYPE));
    assertTrue(node1.isEquivalentToTyped(node2));
  }

  public void testCheckTreeTypeAwareEqualsSameNull() {
    TestErrorReporter testErrorReporter = new TestErrorReporter(null, null);
    JSTypeRegistry registry = new JSTypeRegistry(testErrorReporter);
    Node node1 = Node.newString(Token.NAME, "f");
    Node node2 = Node.newString(Token.NAME, "f");
    assertTrue(node1.isEquivalentToTyped(node2));
  }

  public void testCheckTreeTypeAwareEqualsDifferent() {
    TestErrorReporter testErrorReporter = new TestErrorReporter(null, null);
    JSTypeRegistry registry = new JSTypeRegistry(testErrorReporter);
    Node node1 = Node.newString(Token.NAME, "f");
    node1.setJSType(registry.getNativeType(JSTypeNative.NUMBER_TYPE));
    Node node2 = Node.newString(Token.NAME, "f");
    node2.setJSType(registry.getNativeType(JSTypeNative.STRING_TYPE));
    assertFalse(node1.isEquivalentToTyped(node2));
  }

  public void testCheckTreeTypeAwareEqualsDifferentNull() {
    TestErrorReporter testErrorReporter = new TestErrorReporter(null, null);
    JSTypeRegistry registry = new JSTypeRegistry(testErrorReporter);
    Node node1 = Node.newString(Token.NAME, "f");
    node1.setJSType(registry.getNativeType(JSTypeNative.NUMBER_TYPE));
    Node node2 = Node.newString(Token.NAME, "f");
    assertFalse(node1.isEquivalentToTyped(node2));
  }

  public void testVarArgs1() {
    assertFalse(new Node(1).isVarArgs());
  }

  public void testVarArgs2() {
    Node n = new Node(1);
    n.setVarArgs(false);
    assertFalse(n.isVarArgs());
  }

  public void testVarArgs3() {
    Node n = new Node(1);
    n.setVarArgs(true);
    assertTrue(n.isVarArgs());
  }

  private void testMergeExtract(int lineno, int charno) {
    int linecharno = Node.mergeLineCharNo(lineno, charno);
    assertEquals(lineno, Node.extractLineno(linecharno));
    assertEquals(charno, Node.extractCharno(linecharno));
  }

  public void testFileLevelJSDocAppender() {
    Node n = new Node(1);
    Node.FileLevelJsDocBuilder builder = n.getJsDocBuilderForNode();
    builder.append("foo");
    builder.append("bar");
    assertEquals("foobar", n.getJSDocInfo().getLicense());
  }

  public void testIsQualifiedName() {
    assertTrue(getNode("a").isQualifiedName());
    assertTrue(getNode("$").isQualifiedName());
    assertTrue(getNode("_").isQualifiedName());
    assertTrue(getNode("a.b").isQualifiedName());
    assertTrue(getNode("a_b.cccccc$d4.x.y.zA$").isQualifiedName());
    assertTrue(getNode("this.foo").isQualifiedName());
    assertFalse(getNode("0").isQualifiedName());
    assertFalse(getNode("[]").isQualifiedName());
    assertFalse(getNode("{}").isQualifiedName());
    assertFalse(getNode("''").isQualifiedName());
    assertFalse(getNode("a[b]").isQualifiedName());
    assertFalse(getNode("a[b].c").isQualifiedName());
    assertFalse(getNode("c.a[b]").isQualifiedName());
    assertFalse(getNode("a()").isQualifiedName());
    assertFalse(getNode("a().b").isQualifiedName());
    assertFalse(getNode("b.a()").isQualifiedName());
    assertFalse(getNode("'a'").isQualifiedName());
    assertFalse(getNode("/x/").isQualifiedName());
    assertFalse(getNode("++x").isQualifiedName());
  }

  public void testCloneAnnontations() {
    Node n = getNode("a");
    assertFalse(n.getBooleanProp(Node.IS_CONSTANT_NAME));
    n.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    assertTrue(n.getBooleanProp(Node.IS_CONSTANT_NAME));

    Node nodeClone = n.cloneNode();
    assertTrue(nodeClone.getBooleanProp(Node.IS_CONSTANT_NAME));
  }

  public void testBooleanProp() {
    Node n = getNode("a");

    n.putBooleanProp(Node.IS_CONSTANT_NAME, false);

    assertNull(n.lookupProperty(Node.IS_CONSTANT_NAME));
    assertFalse(n.getBooleanProp(Node.IS_CONSTANT_NAME));

    n.putBooleanProp(Node.IS_CONSTANT_NAME, true);

    assertNotNull(n.lookupProperty(Node.IS_CONSTANT_NAME));
    assertTrue(n.getBooleanProp(Node.IS_CONSTANT_NAME));

    n.putBooleanProp(Node.IS_CONSTANT_NAME, false);

    assertNull(n.lookupProperty(Node.IS_CONSTANT_NAME));
    assertFalse(n.getBooleanProp(Node.IS_CONSTANT_NAME));
  }

  // Verify that annotations on cloned nodes are properly handled.
  public void testCloneAnnontations2() {
    Node n = getNode("a");
    n.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    n.putBooleanProp(Node.IS_DISPATCHER, true);
    assertTrue(n.getBooleanProp(Node.IS_CONSTANT_NAME));
    assertTrue(n.getBooleanProp(Node.IS_DISPATCHER));

    Node nodeClone = n.cloneNode();
    assertTrue(nodeClone.getBooleanProp(Node.IS_CONSTANT_NAME));
    assertTrue(nodeClone.getBooleanProp(Node.IS_DISPATCHER));

    n.putBooleanProp(Node.IS_DISPATCHER, false);
    assertTrue(n.getBooleanProp(Node.IS_CONSTANT_NAME));
    assertFalse(n.getBooleanProp(Node.IS_DISPATCHER));

    assertTrue(nodeClone.getBooleanProp(Node.IS_CONSTANT_NAME));
    assertTrue(nodeClone.getBooleanProp(Node.IS_DISPATCHER));
  }

  private static Node getNode(String js) {
    Node root = parse("var a=(" + js + ");");
    Node expr = root.getFirstChild();
    Node var = expr.getFirstChild();
    return var.getFirstChild();
  }

  private static Node parse(String string) {
    CompilerEnvirons environment = new CompilerEnvirons();
    TestErrorReporter testErrorReporter = new TestErrorReporter(null, null);
    environment.setErrorReporter(testErrorReporter);
    environment.setParseJSDoc(true);
    Parser p = new Parser(environment, testErrorReporter);
    return p.parse(string, null, 0);
  }
}


text:
import React, { Component, PropTypes } from 'react';
import styles from './Track.module.css';

export default class Track extends Component {
  static propTypes = {
    date: PropTypes.string.isRequired,
    artist: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
    album: PropTypes.string.isRequired,
  };

  render() {
    const { date, artist, title, album } = this.props;

    return (

{toDatetime(date)}

{artist}

{title}

{album}

    );
  }
}

function toDatetime(ts) {
  const date = new Date(ts * 1000);
  const hours = date.getHours();
  const minutes = `0${date.getMinutes()}`;
  const seconds = `0${date.getSeconds()}`;
  const formattedTime = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`;
  return formattedTime;
}

redpajama_set_name: RedPajamaGithub


text:
// file: users/List.js

import React, { PropTypes } from 'react';
import Relay from 'react-relay';
import { withRouter, Link } from 'react-router';

// Base components
import Grid, { Cell } from 'react-to-mdl/grid';
import Textfield from 'react-to-mdl/textfield';
import Select from 'react-select';
import Button from 'react-to-mdl/button';
import DataTable, {
  DataTableHead,
  DataTableTH,
  DataTableTD
} from 'react-to-mdl/dataTable';
import Layout, { LayoutIcon } from 'react-to-mdl/layout';

// CSS
import CSSModules from 'react-css-modules';
import { mdlUpgrade } from 'react-to-mdl';
import styles from './styles.scss';

class List extends React.Component {

  static defaultProps = {
    title: 'List of Users'
  }

  constructor(props) {
    super(props)
  }

  render() {
    const { title, users } = this.props;

    return (

        <Grid>
          <Cell col={12}>

{title}

          </Cell>
        </Grid>
        <Grid>
          <Cell offset={3} col={6}>
            <DataTable shadow={'2dp'}>
              <DataTableHead>
                <DataTableTH nonNumeric={true}> User </DataTableTH>
                <DataTableTH nonNumeric={true}> Email </DataTableTH>
                <DataTableTH nonNumeric={true}> Access </DataTableTH>
                <DataTableTH nonNumeric={true}></DataTableTH>
              </DataTableHead>

                {users.map((user, index) => {
                  return

                    <DataTableTD nonNumeric={true}>{`${user.firstName} ${user.lastName}`}</DataTableTD>
                    <DataTableTD nonNumeric={true}>{user.email}</DataTableTD>
                    <DataTableTD nonNumeric={true}>{user.role}</DataTableTD>
                    <DataTableTD nonNumeric={true}>
                      <Link to={`/admin/users/${user.id}/edit`}>edit </Link>
                    </DataTableTD>

                })}

            </DataTable>
          </Cell>
        </Grid>

    )
  }
}

/*** exports ***/
export default withRouter(
  mdlUpgrade(
    CSSModules(List, styles)
  )
);


text:
var resolveSrv = require('./dns.js'),
    EventEmitter = require('events').EventEmitter,
    jptr = require('json-ptr'),
    assert = require('assert-plus'),
    async = require('async');
/**
* Attempts to provide a configuration based on a required configuration input
* @module lib
*/
module.exports =(function () {
  'use strict';

  var CONSUL_HOST = 'CONSUL_HOST',
      CONSUL_PORT = 'CONSUL_PORT',
      CONSUL_SECURE = 'CONSUL_SECURE',
      ee = new EventEmitter(),
      matchSlashGreedy = new RegExp('/', 'g');

  /**
   * Does Service Have Ptr checks to see if a value **bound** to this is present in
   * any of the three fields used to define a JSON Ptr in a service spec
   *
   * This function can be used on its own, but it is intended to be used with the Array.some(...) function
   *
   * @param {object} val - An object, generally expected to be a service specification from configuration-schema.json
   * @returns {boolean} True or false based on whether the bound name 'this' was present in any of the JSON Ptr fields
   */
  function doesServiceHavePtr(val) {
    //Stop jshint from whining about 'this' since this func is explicitly meant
    //to be used with 'bind()'
    /*jshint validthis:true */
    return val.key === this || val.prefix === this || val.suffix === this;
  }

  /**
   * Match and set env var looks for an environment variable given an name prefix and a JSON ptr
   * @param {object} finalConfig - The object to store the value of the env var in if found
   * @param {string} prefix - A prefix to apply to names being looked for in the environment
   * @param {object} ptr - A JSON ptr object
   */
  function matchAndSetEnvVar(finalConfig, prefix, ptr) {
    var requestedProp,
        envVal;
    requestedProp = ptr.pointer.replace(matchSlashGreedy, '_').toUpperCase();
    envVal = process.env[prefix.concat(requestedProp)];
    if (typeof(envVal) === 'undefined') {
      envVal = process.env[requestedProp.substring(1)];
    }
    if (envVal !== undefined) {
      ensureObjPath(finalConfig, ptr);
      ptr.set(finalConfig, envVal);
      return;
    }
  }

  /**
   * Ensure object path is a small utility function for use with JSON pointers that ensures a particular pointer path
   * exists in an object. The function is non-destructive and only creates a path component as necessary.
   * @param {object} object - A JSON object to ensure that a particular pointer path exists in
   * @param {object} ptr - A {@link https://github.com/flitbit/json-ptr|JSON pointer object}
   */
  function ensureObjPath(object, ptr) {
    var cursor = object,
        currentName,
        idx,
        pathAry = ptr.path;
    for (idx = 0; idx < pathAry.length; idx++) {
      currentName = pathAry[idx];
      if (!cursor[currentName]) {
        cursor[currentName] = {};
      }
      cursor = cursor[currentName];
    }

  }

  /**
   * Determines if we should use a consul agent to add configuration
   * @param {object} configurationRequest - A configuration request object that may contain information required to contact a consul agent
   * @returns {object} A reference to an active consule agent if one could be configured, undefined otherwise
   */
  function setupConsul(configRequest) {
    //client must fully specify how we will talk to consul
    var consulClient,
        consulHost = process.env[CONSUL_HOST],
        consulPort = process.env[CONSUL_PORT],
        consulSecure = (process.env[CONSUL_SECURE] === 'true');
    if (consulHost !== undefined &&
    consulPort !== undefined &&
    consulSecure !== undefined) {
      consulClient = require('consul')({
        host: consulHost,
        port: consulPort,
        secure: consulSecure
      });
    }
    return consulClient;
  }

  /**
   * Handles the retrieval of KV pairs from a consul agent, if the given consulClient isn't defined then
   * the method is a no-op
   * @param {object} configRequest - A client provided object that may have a key value section for required key value pairs
   * @param {object} consulClient - A pre-configured client used to communicate with a consul agent, may be undefined to indicate that
   * we are not supposed to use consul
   * @param {object[]} errors - An initially null array of errors that can be added as configuration is processed
   * @param {object} finalConfig - A object in which to store the retrieved configuration
   */
  function createConsulProcessor(configRequest, consulClient, errors, finalConfig) {
    return function processKeyValuePairsInConsul(callback) {
      var requestedKeys = configRequest.keys,
          requestedServices = configRequest.services,
          requestedKey,
          pathPrefixIdx,
          resultIdx,
          result,
          idx,
          resultPtr;
      if (consulClient !== undefined && (requestedKeys || requestedServices)) {
        requestedKeys = requestedKeys || [];
        requestedServices = requestedServices || [];
        async.parallel({
            shared: function(cb){
              consulClient.kv.get({
                key: 'shared/',
                recurse: true
              }, cb);
            },
            specific: function(cb){
              consulClient.kv.get({
                key: configRequest.name + '/',
                recurse: true
              }, cb);
            }
          },
          function (err, results) {
            var foundKeyIdx,
                hasService,
                pathPtr;
            if (err) {
              if (!errors) {
                errors = [];
              }
              errors.push(err);
            } else {
              if (results) {
                //MSH 2015-03-03 The following loop & block deserve some explanation. The goal
                //is to take keys returned from Consul and set config values for services & keys
                //services is, unfortunately, an array of objects with *3* properties that may need
                //to be fulfilled (key, prefix, and suffix).
                for (resultIdx in results) {
                  result = results[resultIdx][0];
                  for (idx = 0; idx < result.length; idx++) {
                    pathPrefixIdx = result[idx].Key.indexOf('/');
                    pathPtr = '#' + result[idx].Key.slice(pathPrefixIdx);
                    foundKeyIdx = requestedKeys.indexOf(pathPtr);
                    resultPtr = jptr.create(pathPtr);
                    if (foundKeyIdx !== -1) {
                      ensureObjPath(finalConfig, resultPtr);
                      resultPtr.set(finalConfig, result[idx].Value);
                    } else {
                      hasService = requestedServices.some(doesServiceHavePtr, pathPtr);
                      if (hasService) {
                        ensureObjPath(finalConfig, resultPtr);
                        resultPtr.set(finalConfig, result[idx].Value);
                      }
                    }
                  }
                }
              }
            }
            callback(null, configRequest, errors, finalConfig);
          });
      } else {
        callback(null, configRequest, errors, finalConfig);
      }
    };
  }

  /**
   * Handles the retrieval of KV pairs from the application's runtime environment
   * @param {object} configRequest - A client provided object that may have a key value section for required key value pairs
   * @param {object[]} errors - An initially null array of errors that can be added as configuration is processed
   * @param {object} finalConfig - A object in which to store the retrieved configuration
   */
  function processKeyValuesPairsInEnv(configRequest, errors, finalConfig, callback) {
    var requestedKeys = configRequest.keys,
        requestedServices = configRequest.services,
        prefix,
        ptr,
        idx;
    if (configRequest.name) {
      prefix = configRequest.name.toUpperCase();
      prefix = prefix.replace(/-/g, '_');
    } else {
      prefix = '';
    }
    if (requestedKeys) {
      for (idx = 0; idx < requestedKeys.length; idx++) {
        ptr = jptr.create(requestedKeys[idx]);
        matchAndSetEnvVar(finalConfig, prefix, ptr);
      }
    }
    if (requestedServices) {
      for (idx = 0; idx < requestedServices.length; idx++) {
        ptr = jptr.create(requestedServices[idx].key);
        matchAndSetEnvVar(finalConfig, prefix, ptr);
        if (requestedServices[idx].prefix) {
          ptr = jptr.create(requestedServices[idx].prefix);
          matchAndSetEnvVar(finalConfig, prefix, ptr);
        }
        if (requestedServices[idx].suffix) {
          ptr = jptr.create(requestedServices[idx].suffix);
          matchAndSetEnvVar(finalConfig, prefix, ptr);
        }
      }
    }
    callback(null, configRequest, errors, finalConfig);
  }

  /**
  * Handles the retrieval of KV pairs based on DNS SRV requests
  * @param {object} configRequest - A client provided object that may have a services section
  * @param {object[]} errors - An initially null array of errors that can be added as configuration is processed
  * @param {object} finalConfig - A object in which to store the retrieved configuration
  */
  function processServicesInDNS(configRequest, errors, finalConfig, callback) {
    assert.optionalArrayOfObject(configRequest.services, 'configRequest.services');
    if (configRequest.services !== undefined) {
      resolveSrv(configRequest, finalConfig, function (err, config) {
        var serviceName,
            ptr;
        if (!err) {
          for (serviceName in config) {
            if (config.hasOwnProperty(serviceName)) {
              ptr = jptr.create(config[serviceName].key);
              ensureObjPath(finalConfig, ptr);
              ptr.set(finalConfig, config[serviceName].value);
            }
          }
        } else {
          if (!errors) {
            errors = [];
          }
          errors.push(err);
        }
        callback(null, configRequest, errors, finalConfig);
      });
    } else {
      callback(null, configRequest, errors, finalConfig);
    }

  }

  /**
   * Finish processing wraps up configuration processing and determines if required parameters were met
   * @param {object} configRequest - A client provided object that determines the configuration to request
   * @param {object[]} errors - An initially null array of errors that can be added as configuration is processed
   * @param {object} finalConfig - The output configuration object
   */
  function finishProcessing(configRequest, errors, finalConfig, callback) {
    var ptr,
        idx,
        optionalSet = {},
        keyToCheck;
    if (configRequest.optional) {
      for (idx = 0; idx < configRequest.optional.length; idx++) {
        optionalSet[configRequest.optional[idx]] = true;
      }
    }
    if (configRequest.keys) {
      for (idx = 0; idx < configRequest.keys.length; idx++) {
        keyToCheck = configRequest.keys[idx];
        //if the key was *not* optional and the key was not in our final config object then....
        if (!(keyToCheck in optionalSet) && jptr.create(keyToCheck).get(finalConfig) === undefined) {
          if (errors === null) {
            errors = [];
          }
          errors.push(new Error('Missing key value specified by ['.concat(configRequest.name, ']', keyToCheck)));
        }
      }
    }
    if (configRequest.services) {
      for (idx = 0; idx < configRequest.services.length; idx++) {
        keyToCheck = configRequest.services[idx].key;
        if (!(keyToCheck in optionalSet) && jptr.create(keyToCheck).get(finalConfig) === undefined) {
          if (errors === null) {
            errors = [];
          }
          errors.push(new Error('Missing service key value specified by service with name ['.concat(configRequest.name, ']', keyToCheck)));
        }
      }
    }
    callback(errors, finalConfig);
  }

  //Client facing code

  /**
   * @callback doneCallback
   * @param {object[]} err - An array of configuration errors, if not null then at least one configuration values failed to be retrieved
   * @param {object} config - The finished configuration object
   */

  /**
   * Allows a client to request configuration
   * @name module:lib
   * @param {object} config - A env-configurator config object that determines what properties will be looked up
   * @param {doneCallback} callback - A callback function to notify the client of the library with the new configuration object
   */
  function getConfiguration(config, callback) {
    assert.func(callback, 'callback');
    assert.object(config, 'config');
    var finalConfig = {};
    var consulClient = setupConsul(config);
    async.waterfall([
      createConsulProcessor(config, consulClient, null, finalConfig),
      processKeyValuesPairsInEnv,
      processServicesInDNS,
      finishProcessing
    ], callback);
  }

  return getConfiguration;
})();


text:
This contains the Worker API Thrift definition, generated code, and worker
server and client implementations.


text:
/*
 */
/*
modification history
--------------------
4-27-04,gmb  created
*/

// #define TIMING_DIAG_ON    /* compile in timing diagnostics */

#ifndef ALLREADY_POSIX
 #define _POSIX_SOURCE /* defined when source is to be POSIX-compliant */
#endif
#include <string.h>
#include <vxWorks.h>
#include <stdioLib.h>
#include <sysLib.h>
#include <semLib.h>
#include <rngLib.h>
#include <msgQLib.h>

#include "expDoneCodes.h"
#include "errorcodes.h"
#include "instrWvDefines.h"
#include "taskPriority.h"
#include "nvhardware.h"

#include "logMsgLib.h"

#include "NDDS_Obj.h"
#include "NDDS_PubFuncs.h"
#include "NDDS_SubFuncs.h"

#include "Monitor_Cmd.h"
#include "Cntlr_Comm.h"

#ifdef RTI_NDDS_4x
#include "Monitor_CmdPlugin.h"
#include "Cntlr_CommPlugin.h"
#include "Monitor_CmdSupport.h"
#include "Cntlr_CommSupport.h"
#endif

#include "AParser.h"
#include "cntlrStates.h"
#include "flashUpdate.h"
#include "tune.h"
#include "sysUtils.h"

extern int  BrdType;    /* Type of Board, RF, Master, PFG, DDR, Gradient, Etc. */
extern int  BrdNum;     /* The Board types Ordinal number, i.e. rf1 or rf2 */

#define HOSTNAME_SIZE 80
extern char hostName[HOSTNAME_SIZE];

extern NDDS_ID NDDS_Domain;

extern ACODE_ID pTheAcodeObject;

extern MSG_Q_ID pMsgesToAParser;   /* MsgQ used for Msges to Acode Parser */

NDDS_ID pCntlrPub, pCntlrSub;   /* multicast pub/sun to all controllers */

static SEM_ID pCntlrPubMutex = NULL;

/* subscriber to create subscriptions to contoller publications dynamicly */
#ifndef RTI_NDDS_4x
NDDSSubscriber CntlrSubscriber;
#endif

/* subscriptions to controller publications */
#ifndef RTI_NDDS_4x
#define MAX_NEXUS_SUBS 128
NDDS_ID pCntrlSubs[MAX_NEXUS_SUBS];

int numCntrlSubs = 0;
#endif

static SEM_ID pExceptionPubMutex = NULL;
NDDS_ID pExceptionPub, pExceptionSub;   /* multicast pub/sun to all controllers includeing master for errors/warnings */

extern int DebugLevel;

extern MSG_Q_ID  pTuneMsgQ;  /* Message Q to Tune Task */
static int callbackParam = 0;

#ifdef RTI_NDDS_4x
static int masterCallbackParam = 0;
static int cntlrCallbackParam = 1;
#endif

static MSG_Q_ID  pMsgesToFFSUpdate = NULL;   /* MsgQ used for Msges to Flash Update */

int patternType = 0;

union lltw {
     unsigned long long lldur;
     unsigned int  idur[2];
};

/*
 *   The NDDS callback routine, the routine is call when an issue of the subscribed topic
 *   is delivered.
 *   called with the context of the NDDS task n_rtu7400
 *
 */
#ifndef RTI_NDDS_4x

RTIBool Cntlr_CommCallback(const NDDSRecvInfo *issue, NDDSInstance *instance,
                             void *callBackRtnParam)
{
    Cntlr_Comm *recvIssue;
    void MasterNexus(Cntlr_Comm *issue);
    void CntlrPlexus(Cntlr_Comm *issue);
    int *param;

    if (issue->status == NDDS_FRESH_DATA)
    {
        recvIssue = (Cntlr_Comm *) instance;
        param = (int *) callBackRtnParam;
        DPRINT5(3,"Cntlr_Comm CallBack:  cmd: %d, arg1: %d, arg2: %d, arg3: %d, crc: 0x%lx\n",
          recvIssue->cmd,recvIssue->arg1, recvIssue->arg2, recvIssue->arg3, recvIssue->crc32chksum);
        if (*param == 0)
        {
	  /* DPRINT(-1,"calling MasterNexus()\n"); */
          MasterNexus(recvIssue);
        }
        else
        {
	  /* DPRINT(-1,"calling CntlrPlexus()\n"); */
          CntlrPlexus(recvIssue);
        }
    }
   return RTI_TRUE;
}

#else /* RTI_NDDS_4x */
void Cntlr_CommCallback(void* listener_data, DDS_DataReader* reader)
{
   Cntlr_Comm *recvIssue;
   struct DDS_SampleInfo* info = NULL;
   struct DDS_SampleInfoSeq info_seq = DDS_SEQUENCE_INITIALIZER;
   DDS_ReturnCode_t retcode;
   DDS_Boolean result;
   long i,numIssues;
   void MasterNexus(Cntlr_Comm *issue);
   void CntlrPlexus(Cntlr_Comm *issue);
   int *param;
   DDS_TopicDescription *topicDesc;

   struct Cntlr_CommSeq data_seq = DDS_SEQUENCE_INITIALIZER;
   Cntlr_CommDataReader *CntlrComm_reader = NULL;

   CntlrComm_reader = Cntlr_CommDataReader_narrow(pCntlrSub->pDReader);
   if ( CntlrComm_reader == NULL)
   {
        errLogRet(LOGIT,debugInfo,"DataReader narrow error\n");
        return;
   }

   topicDesc = DDS_DataReader_get_topicdescription(reader);
   DPRINT2(3,"Cntlr_CommCallback: Type: '%s', Name: '%s'\n",
      DDS_TopicDescription_get_type_name(topicDesc), DDS_TopicDescription_get_name(topicDesc));

   while(1)
   {
        // Given DDS_HANDLE_NIL as a parameter, take_next_instance returns
        // a sequence containing samples from only the next (in a well-determined
        // but unspecified order) un-taken instance.
        retcode =  Cntlr_CommDataReader_take_next_instance(
            CntlrComm_reader,
            &data_seq, &info_seq, DDS_LENGTH_UNLIMITED,
            &DDS_HANDLE_NIL,
            DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

        // retcode = Cntlr_CommDataReader_take(CntlrComm_reader,
        //                      &data_seq, &info_seq,
        //                      DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
        //                      DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

        if (retcode == DDS_RETCODE_NO_DATA) {
                 break; // return;
        } else if (retcode != DDS_RETCODE_OK) {
                 errLogRet(LOGIT,debugInfo,"next instance error %d\n",retcode);
                 break; // return;
        }

        numIssues = Cntlr_CommSeq_get_length(&data_seq);
        DPRINT1(+3,"Cntlr_Comm CallBack: numIssues: %d\n",numIssues);

        for (i=0; i < numIssues; i++)
        {
           info = DDS_SampleInfoSeq_get_reference(&info_seq, i);
           if (info->valid_data)
           {

              recvIssue = (Cntlr_Comm *) Cntlr_CommSeq_get_reference(&data_seq,i);

              param = (int *) listener_data;
              // DPRINT6(-5,"-- parm: 0x%lx, %d, master: 0x%lx, 0x%lx, cntlr: 0x%lx, 0x%lx\n",
              //   param, *param, &masterCallbackParam,masterCallbackParam, &cntlrCallbackParam,cntlrCallbackParam);
              DPRINT2(3,"Cntlr_Comm CallBack: Key: %d, Cntlr: '%s'\n",recvIssue->key,recvIssue->cntlrId);
              DPRINT5(3,"Cntlr_Comm CallBack:  cmd: %d, arg1: %d, arg2: %d, arg3: %d, crc: 0x%lx\n",
                recvIssue->cmd,recvIssue->arg1, recvIssue->arg2, recvIssue->arg3, recvIssue->crc32chksum);
             if (*param == 0)
             {
               /* DPRINT(-1,"calling MasterNexus()\n"); */
               MasterNexus(recvIssue);
             }
             else
             {
               /* DPRINT(-1,"calling CntlrPlexus()\n"); */
               CntlrPlexus(recvIssue);
             }
           }
        }
        retcode = Cntlr_CommDataReader_return_loan( CntlrComm_reader,
                  &data_seq, &info_seq);
        DDS_SampleInfoSeq_set_maximum(&info_seq, 0);
   } // while
   return;
}

#endif /* RTI_NDDS_4x */

/*
 * Used by Master, to make it usage clear
 * just initial routine to send cmds, not complete yet
 * not all structure member filled in
 *
 */
#ifndef RTI_NDDS_4x
cntlrCommPub(int cmd,int arg1,int arg2,int arg3,char *strmsg)
{
   Cntlr_Comm *issue;
   issue = pCntlrPub->instance;
   semTake(pCntlrPubMutex, WAIT_FOREVER);
   DPRINT(+3,"cntlrCommPub: got Mutex\n");
   issue->cmd  = cmd;  /* atoi( token ); */
   issue->arg1 = arg1;
   issue->arg2 = arg2;
   issue->arg3 = arg3;
   /* issue->errorcode */
   /* issue->warningcode */
   /* issue-> crc32chksum */

   if (strmsg != NULL)
   {
     int strsize = strlen(strmsg);
     if (strsize <= COMM_MAX_STR_SIZE)
       strncpy(issue->msgstr,strmsg,COMM_MAX_STR_SIZE);
     else
     {
       DPRINT2(-1,"msg to long: %d, max: %d\n",strsize,COMM_MAX_STR_SIZE);
     }
   }
   nddsPublishData(pCntlrPub);
   DPRINT(+3,"cntlrCommPub: give Mutex\n");
   semGive(pCntlrPubMutex);
   return 0;
}

#else /* RTI_NDDS_4x */
/* the RTI NDDS 4x Varient */
cntlrCommPub(int cmd,int arg1,int arg2,int arg3,char *strmsg)
{
   DDS_ReturnCode_t result;
   DDS_InstanceHandle_t instance_handle = DDS_HANDLE_NIL;
   Cntlr_CommDataWriter *CntlrCmd_writer = NULL;
   Cntlr_Comm *issue;

   issue = pCntlrPub->instance;
   semTake(pCntlrPubMutex, WAIT_FOREVER);
   DPRINT(+3,"cntlrCommPub: got Mutex\n");
   issue->cmd  = cmd;  /* atoi( token ); */
   issue->arg1 = arg1;
   issue->arg2 = arg2;
   issue->arg3 = arg3;
   /* issue->errorcode */
   /* issue->warningcode */
   /* issue-> crc32chksum */

   if (strmsg != NULL)
     {
       int strsize = strlen(strmsg);
       if (strsize <= COMM_MAX_STR_SIZE)
	 strncpy(issue->msgstr,strmsg,COMM_MAX_STR_SIZE);
       else
         {
           errLogRet(LOGIT,debugInfo,"msg to long: %d, max: %d \n",strsize,COMM_MAX_STR_SIZE);
         }
     }
   CntlrCmd_writer = Cntlr_CommDataWriter_narrow(pCntlrPub->pDWriter);
   if (CntlrCmd_writer == NULL) {
     errLogRet(LOGIT,debugInfo,"DataWriter narrow error\n");
     semGive(pCntlrPubMutex);
     return -1;
   }

   // instance_handle = pCntlrPub->issueRegHandle;
   result = Cntlr_CommDataWriter_write(CntlrCmd_writer,
				       issue,&instance_handle);
   if (result != DDS_RETCODE_OK) {
     errLogRet(LOGIT,debugInfo,"DataWriter write error: %d\n",result);
   }
   DPRINT(+3,"cntlrCommPub: give Mutex\n");
   semGive(pCntlrPubMutex);
   return 0;
}

#endif /* RTI_NDDS_4x */

wait4Pub2BSent()
{
   nddsPublicationIssuesWait(pCntlrPub, 10, 0);
}

/*
 * In reality these call the same routine, the difference being that
 * the publications built have different 'topic' names between the master
 * and all other controllers.
 * These functions are just provided so that the intent is clear.
 *
 *    Author: Greg Brissey   9/20/04
 */
send2Master(int cmd,int arg1,int arg2,int arg3,char *strmsg)
{
    DPRINT(+3,"send2Master\n");
    cntlrCommPub(cmd,arg1,arg2,arg3,strmsg);
    return 0;
}

send2MasterTicks(long long ticks)
{
    union lltw TEMP;
    TEMP.lldur = ticks;
    DPRINT(+3,"send2MasterTicks\n");
    cntlrCommPub(CNTLR_CMD_SET_FIFOTICK,TEMP.idur[0],TEMP.idur[1],0,NULL);
    return 0;
}

send2AllCntlrs(int cmd, int arg1,int arg2,int arg3,char *strmsg)
{
    DPRINT(+3,"send2AllCntlrs\n");
    cntlrCommPub(cmd,arg1,arg2,arg3,strmsg);
    return 0;
}

/*
 * The Master Nexus, this is where all commnunication from the 'other'
 * controllers come.
 * Typical usage will be for controllers reporting in on status, errors or warnings,
 * or possible command for the master hardware (serialports [VT,Shims,etc.])
 *
 *   Author: Greg Brissey 4/27/04
 */
void MasterNexus(Cntlr_Comm *issue)
{
   int len,errorcode;
   int cmd;
   Cntlr_Comm  cmdIssue;
   DPRINT4(+2,"MasterPlexus cmd: %d, arg1: %d, arg2: %d, arg3: %d\n", issue->cmd,
		issue->arg1,issue->arg2,issue->arg3);

   switch( issue->cmd )
   {
     case CNTLR_CMD_HERE:
	  {
   	        /* DPRINT(-1,"HERE\n"); */
#ifdef INSTRUMENT
	        wvEvent(EVENT_NEXUS_RCALLREPLY,NULL,NULL);
#endif
		DPRINT2(-1,"Cntlr: '%s' Acknowledged ROLLCALL, with: '%s'.\n",
			issue->cntlrId,getCntlrStateStr(issue->arg1));
		DPRINT2(-1,"Cntlr: '%s', ConfigInfo: %d\n",issue->cntlrId,issue->arg2);
		errorcode = cntlrStatesAdd(issue->cntlrId,issue->arg1,issue->arg2);
		/* -1 == controller already in list, 0 = controller added */
		DPRINT2(+1,"Cntlr: '%s': %s in Cntlr List\n", issue->cntlrId,
			((errorcode == -1) ? "Already Present" : "Added"));
#ifdef INSTRUMENT
		wvEvent(EVENT_NEXUS_RCALLREPLY_CMPLT,NULL,NULL);
#endif
	  }
	  break;

     case CNTLR_CMD_READY4SYNC:
	  {
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_READY4SYNC,NULL,NULL);
#endif
   	        /* DPRINT1(-1,"Cntlr: '%s', reporting READY FOR SYNC\n",issue->cntlrId); */
   	        DPRINT2(-1,"Cntlr: '%s', Reported: '%s'.\n",
				issue->cntlrId,getCntlrStateStr(issue->arg1));
#ifdef TIMING_DIAG_ON
   {
      double delta,duration;
      double getTimeStampDurations(double *delta,double *duration);
      updateTimeStamp(0);
      getTimeStampDurations(&delta,&duration);
      DPRINT3(-19,"'%s': reporting READY4SYNC: delta: %lf usec, duration: %lf usec\n",issue->cntlrId,delta,duration);
      updateTimeStamp(0); /* remove time use to perform this printing for next TSPRINT */ \
   }
#endif
                errorcode = cntlrSetState(issue->cntlrId,issue->arg1, 0 /* errorcode */ );
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_READY4SYNC_CMPLT,NULL,NULL);
#endif
	  }
	  break;

     case CNTLR_CMD_STATE_UPDATE:
	  {
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_STATEUPDATE,NULL,NULL);
#endif
        DPRINT3(-1,"Cntlr: '%s', reported Updated State: '%s', errorcode: %d.\n",
                           issue->cntlrId,getCntlrStateStr(issue->arg1),issue->arg2);
#ifdef TIMING_DIAG_ON
   {
      double delta,duration;
      double getTimeStampDurations(double *delta,double *duration);
      updateTimeStamp(0);
      getTimeStampDurations(&delta,&duration);
      DPRINT4(-19,"'%s': StateUpdate2: '%s', delta: %lf usec, duration: %lf usec\n",
            issue->cntlrId,getCntlrStateStr(issue->arg1),delta,duration);
      updateTimeStamp(0); /* remove time use to perform this printing for next TSPRINT */ \
   }
#endif

       errorcode = cntlrSetState(issue->cntlrId,issue->arg1, issue->arg2 /* errorcode */ );

       /* cntlrStateShow(); */
#ifdef INSTRUMENT
	    wvEvent(EVENT_NEXUS_STATEUPDATE_CMPLT,NULL,NULL);
#endif
	  }
	  break;

     case CNTLR_CMD_SET_ACQSTATE:
	  {
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_ACQSTATE,NULL,NULL);
#endif
   	        DPRINT2(-1,"Cntlr: '%s', set Acqstate: %d\n",
                           issue->cntlrId,issue->arg1);
                     /* issue->cntlrId,getAcqStateStr(issue->arg1)); */
                setAcqState(issue->arg1);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_ACQSTATE_CMPLT,NULL,NULL);
#endif
	  }
	  break;

     case CNTLR_CMD_SET_FIFOTICK:
	  {
            union lltw TEMP;
            TEMP.idur[0] = issue->arg1;  /* FifoCumDurationHi; */
            TEMP.idur[1] = issue->arg2;   /* pFifoCumDurationLow; */
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_STATEUPDATE,NULL,NULL);
#endif
   	        DPRINT3(+1,"Cntlr: '%s', reported Fifo Ticks: 0x%llx, %lld\n",
                           issue->cntlrId,TEMP.lldur,TEMP.lldur);
                errorcode = cntlrSetFifoTicks(issue->cntlrId,TEMP.lldur);
                /* cntlrStateShow(); */
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_STATEUPDATE_CMPLT,NULL,NULL);
#endif
	  }
	  break;

/* was going to put autolock on lock controller, but many things are controlled
   by master and it just makes it simpler at this point to put it on the master

        GMB    1/6/05
*/
#ifdef AUTOLOCK_ON_LOCKCNTLR

     case CNTLR_CMD_SET_SHIMDAC:
	  {
                int zero;
                int oneDac[4];
   	        DPRINT3(-1,"Cntlr: '%s', set Shim DAC#: %d, Value: %d\n",
                           issue->cntlrId,issue->arg1,issue->arg2);
		zero=0;
	        oneDac[0] = 13;
	        oneDac[1] = issue->arg1;    /* Z0 = 1 */
	        oneDac[2] = issue->arg2;
                /* if put in then all controller need a dummy shimHandler() func */
		// shimHandler(oneDac,&zero,3,0);   // count=1, fifoFlag=false
	  }
	  break;

#endif

     default:
	    DPRINT1(-5,"MasterNexus: Unknown command: %d\n",issue->cmd);
            break;

   }
   return;
}

/*********************************************************************
*
*  The Controller Communication Plexus with the Master controller
*  The 'Other' (not master)  controllers get their message decoded here.
*  Typically the master send commands here, however other controllers
*  might send commands to one another, thus not going through the master.
*
*					Author Greg Brissey 4-26-04
*/
void CntlrPlexus(Cntlr_Comm *issue)
{
   int len;
   int cmd;
   Cntlr_Comm  cmdIssue;

   DPRINT4(+2,"CntlrPlexus cmd: %d, arg1: %d, arg2: %d, arg3: %d\n", issue->cmd,
		issue->arg1,issue->arg2,issue->arg3);

   switch( issue->cmd )
   {
     case CNTLR_CMD_ROLLCALL:
	  {
          int result;
          // RF_CONFIG_STD = 0 - default for all controllers config
          int ConfigInfo = RF_CONFIG_STD;

	  DPRINT(-1,"CntlrPlexus(): ROLLCALL\n");
          #ifdef SILKWORM
          if (BrdType == RF_BRD_TYPE_ID)
          {
             result = execFunc("getRfType",NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
   	       DPRINT1(-1,"CntlrPlexus(): ROLLCALL, getRfTpe result: %d\n",result);
             if ( result == 0 )
                ConfigInfo = RF_CONFIG_STD;
             else if( result == 1 )
                ConfigInfo = RF_CONFIG_ICAT;
             else
                ConfigInfo =  RF_CONFIG_UNSET;
          }
          #endif
	  if (BrdType == LPFG_BRD_TYPE_ID)
	    ConfigInfo = PFG_CONFIG_LOCK;

	  send2Master(CNTLR_CMD_HERE,CNTLR_READYnIDLE,ConfigInfo,0,NULL); /* NO_WAIT, MSG_PRI_NORMAL); */
	  }
	  break;

     case CNTLR_CMD_SET_DEBUGLEVEL:
          DebugLevel = issue->arg1;
          DPRINT1(-1,"CntlrPlexus(): SET_DEBUGLEVEL: DebugLevel = %d\n",DebugLevel);
	  break;

     case CNTLR_CMD_REBOOT:
          DPRINT(-1,"CntlrPlexus(): ReBooting\n");
          reboot();
	  break;

     case CNTLR_CMD_APARSER:
          {
	    PARSER_MSG pCmd;
            if (BrdType != LOCK_BRD_TYPE_ID)
            {

#ifdef INSTRUMENT
	       wvEvent(EVENT_NEXUS_APARSE,NULL,NULL);
#endif
   	       DPRINT5(-1,"CntlrPlexus(): APARSER: cmd: %d, Acodes: %d, Tables: %d, start FId: %d, Basename: '%s'\n",
		       issue->cmd,issue->arg1,issue->arg2,issue->arg3,issue->msgstr);
               pCmd.parser_cmd = issue->cmd;
	       pCmd.NumAcodes = issue->arg1;
	       pCmd.NumTables = issue->arg2;
	       pCmd.startFID = issue->arg3;
	       strncpy(pCmd.AcqBaseBufName,issue->msgstr, EXP_BASE_NAME_SIZE);
     	       msgQSend(pMsgesToAParser,(char*) &pCmd, sizeof(PARSER_MSG), NO_WAIT, MSG_PRI_NORMAL);
#ifdef INSTRUMENT
	       wvEvent(EVENT_NEXUS_APARSE_CMPLT,NULL,NULL);
#endif
            }
          }
	  break;

     case CNTLR_CMD_FFS_UPDATE:
          {
            FLASH_UPDATE_MSG  ffsMsge;
            MSG_Q_ID startFlashUpdate(int taskpriority,int taskoptions,int stacksize);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_FFSUPDATE_CMPLT,NULL,NULL);
#endif
            if (pMsgesToFFSUpdate == NULL)
            {
		DPRINT(-1,"Start FlashFS Update Task.\n");
                pMsgesToFFSUpdate = startFlashUpdate(FFSUPDATE_TASK_PRIORITY,STD_TASKOPTIONS,256*1024);
            }
            DPRINT(-1,"========>> FLASH_UPDATE: Initiate FLASH Update\n");
            DPRINT3(-1,"cmd: %d, filesize: %ld, msge: '%s'\n",issue->cmd,issue->arg1,issue->msgstr);
            ffsMsge.cmd = issue->cmd;
            ffsMsge.filesize = issue->arg1;   /* file size */
            ffsMsge.arg2 = issue->arg3;	      /* defered update flag */
            ffsMsge.arg3 = 0;
            ffsMsge.crc32chksum = issue->crc32chksum;
            strncpy(ffsMsge.msgstr,issue->msgstr,MAX_FLASH_UPDATE_MSG_STR);

            DPRINT3(-1,"cmd: %d, filesize: %ld, msge: '%s'\n",ffsMsge.cmd,ffsMsge.filesize,ffsMsge.msgstr);

     	    msgQSend(pMsgesToFFSUpdate,(char*) &ffsMsge, sizeof(FLASH_UPDATE_MSG), WAIT_FOREVER, MSG_PRI_NORMAL);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_FFSUPDATE_CMPLT,NULL,NULL);
#endif
          }
	  break;

     case CNTLR_CMD_FFS_COMMIT:
          {
            FLASH_UPDATE_MSG  ffsMsge;
            MSG_Q_ID startFlashUpdate(int taskpriority,int taskoptions,int stacksize);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_FFSCOMMIT,NULL,NULL);
#endif
            if (pMsgesToFFSUpdate == NULL)
            {
		DPRINT(-1,"Start FlashFS Update Task.\n");
                pMsgesToFFSUpdate =  startFlashUpdate(70,STD_TASKOPTIONS,256*1024);
            }
            DPRINT(-1,"========>> FLASH_UPDATE: Initiate FLASH Commit\n");
            ffsMsge.cmd = issue->cmd;
            ffsMsge.filesize = issue->arg1;   /* file size */
            ffsMsge.arg2 = issue->arg3;	      /* defered update flag */
            ffsMsge.arg3 = 0;
            ffsMsge.crc32chksum = issue->crc32chksum;
            strncpy(ffsMsge.msgstr,issue->msgstr,MAX_FLASH_UPDATE_MSG_STR);

            DPRINT3(-1,"cmd: %d, filesize: %ld, msge: '%s'\n",ffsMsge.cmd,ffsMsge.filesize,ffsMsge.msgstr);
     	    msgQSend(pMsgesToFFSUpdate,(char*) &ffsMsge, sizeof(FLASH_UPDATE_MSG), WAIT_FOREVER, MSG_PRI_NORMAL);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_FFSCOMMIT_CMPLT,NULL,NULL);
#endif
          }
	  break;

     case CNTLR_CMD_FFS_DELETE:
          {
            FLASH_UPDATE_MSG  ffsMsge;
            MSG_Q_ID startFlashUpdate(int taskpriority,int taskoptions,int stacksize);
            if (pMsgesToFFSUpdate == NULL)
            {
		DPRINT(-1,"Start FlashFS Update Task.\n");
                pMsgesToFFSUpdate =  startFlashUpdate(70,STD_TASKOPTIONS,256*1024);
            }
            DPRINT(-1,"========>> FLASH_DELETE: Initiate FLASH Delete\n");
            ffsMsge.cmd = issue->cmd;
            ffsMsge.filesize = 0;   /* file size */
            ffsMsge.arg2 = 0;
            ffsMsge.arg3 = 0;
            ffsMsge.crc32chksum = issue->crc32chksum;
            strncpy(ffsMsge.msgstr,issue->msgstr,MAX_FLASH_UPDATE_MSG_STR);

            DPRINT3(-1,"cmd: %d, filesize: %ld, msge: '%s'\n",ffsMsge.cmd,ffsMsge.filesize,ffsMsge.msgstr);
     	    msgQSend(pMsgesToFFSUpdate,(char*) &ffsMsge, sizeof(FLASH_UPDATE_MSG), WAIT_FOREVER, MSG_PRI_NORMAL);
          }
          break;

     case CNTLR_CMD_TUNE_QUIET:
     case CNTLR_CMD_TUNE_ENABLE:
     case CNTLR_CMD_TUNE_FINI:
          {
            TUNE_MSG  tuneMsge;
            DPRINT( 1,"========>> TUNE CMD  <<========== \n");
            tuneMsge.cmd = issue->cmd;
            tuneMsge.channel = issue->arg1;   /* file size */
            tuneMsge.arg2 = issue->arg2;
            tuneMsge.arg3 = issue->arg3;
            tuneMsge.crc32chksum = issue->crc32chksum;
            strncpy(tuneMsge.msgstr,issue->msgstr,MAX_FLASH_UPDATE_MSG_STR);
            DPRINT4( 1,"cmd: %d, channel: %ld, atten: %d, msge: '%s'\n",
                       tuneMsge.cmd,tuneMsge.channel,tuneMsge.arg2,tuneMsge.msgstr);
            if (pTuneMsgQ != NULL)
     	          msgQSend(pTuneMsgQ,(char*) &tuneMsge, sizeof(TUNE_MSG), WAIT_FOREVER, MSG_PRI_NORMAL);
          }
          break;
#ifdef NO_DIFF_CASES
     case CNTLR_CMD_TUNE_ENABLE:
          {
            TUNE_MSG  tuneMsge;
          }
          break;
     case CNTLR_CMD_TUNE_FINI:
          {
            TUNE_MSG  tuneMsge;
          }
          break;
#endif
     case CNTLR_RTVAR_UPDATE:
          {
            if (BrdType != LOCK_BRD_TYPE_ID)
            {
               int *rtVar =  (int *)pTheAcodeObject->pLcStruct;
#ifdef INSTRUMENT
	       wvEvent(EVENT_NEXUS_RTVARUPDATE,NULL,NULL);
#endif
	       DPRINT2( 1,"CNTLR_RTVAR_UPDATE: index=%d value=%d\n",
				issue->arg1,issue->arg2);
               rtVar[issue->arg1] = issue->arg2;
               semGive(pTheAcodeObject->pSemParseSuspend);
#ifdef INSTRUMENT
	       wvEvent(EVENT_NEXUS_RTVARUPDATE_CMPLT,NULL,NULL);
#endif
            }
          }
          break;

     default:
	    DPRINT1(-5,"CntlrPlexus: Unknown command: %d\n",issue->cmd);
            break;

   }
   return;
}

/*
 * Create a Publication Topic to communicate with the Cntrollers/Master
 *
 *					Author Greg Brissey 4-26-04
 */
NDDS_ID createCntlrCommPub(NDDS_ID nddsId, char *topic, const char *cntlrName)
{
    int result;
    NDDS_ID pPubObj;
    char pubtopic[128];
    Cntlr_Comm  *issue;

    /* Build Data type Object for both publication and subscription to Expproc */
    /* ------- malloc space for data type object --------- */
    if ( (pPubObj = (NDDS_ID) malloc( sizeof(NDDS_OBJ)) ) == NULL )
        return(NULL);

    /* create the pub issue  Mutual Exclusion semaphore */
    if (pCntlrPubMutex == NULL)
	pCntlrPubMutex = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE |
				    SEM_DELETE_SAFE);

    /* zero out structure */
    memset(pPubObj,0,sizeof(NDDS_OBJ));
    memcpy(pPubObj,nddsId,sizeof(NDDS_OBJ));

    strcpy(pPubObj->topicName,topic);
    pPubObj->pubThreadId = 42; /* DEFAULT_PUB_THREADID; taskIdSelf(); */

    /* fills in dataTypeName, TypeRegisterFunc, TypeAllocFunc, TypeSizeFunc */
    getCntlr_CommInfo(pPubObj);

    DPRINT2(+1,"Create Pub topic: '%s' for Cntlr: '%s'\n",pPubObj->topicName,cntlrName);

#ifdef RTI_NDDS_4x
  /*
  #ifdef PFG_LOCK_COMBO_CNTLR // has more readers/writers than single-function controllers
    pPubObj->queueSize  = 4;
    pPubObj->AckRequestsPerSendQueue = 4;
    pPubObj->highWaterMark = 2;
  #else
  */
    pPubObj->queueSize  = 2;
    pPubObj->AckRequestsPerSendQueue = 2;
    pPubObj->highWaterMark = 1;
  //#endif
    pPubObj->lowWaterMark =  0;
    initPublication(pPubObj);
#endif /* RTI_NDDS_4x */
    createPublication(pPubObj);
    issue = (Cntlr_Comm  *) pPubObj->instance;
    strcpy(issue->cntlrId,cntlrName);   /* fill in the constant cntlrId string */
    return pPubObj;
}

/*
 * Create a Subscription Topic to communicate with the Controllers/Master
 *
 *					Author Greg Brissey 4-26-04
 */
NDDS_ID createCntlrCommSub(NDDS_ID nddsId, char *topic, char *multicastIP, void *callbackArg)
{

   NDDS_ID  pSubObj;
   char subtopic[128];

    /* Build Data type Object for both publication and subscription to Expproc */
    /* ------- malloc space for data type object --------- */
    if ( (pSubObj = (NDDS_ID) malloc( sizeof(NDDS_OBJ)) ) == NULL )
        return NULL;

    /* zero out structure */
    memset(pSubObj,0,sizeof(NDDS_OBJ));
    memcpy(pSubObj,nddsId,sizeof(NDDS_OBJ));

    strcpy(pSubObj->topicName,topic);

    /* fills in dataTypeName, TypeRegisterFunc, TypeAllocFunc, TypeSizeFunc */
    getCntlr_CommInfo(pSubObj);

#ifndef RTI_NDDS_4x
    pSubObj->callBkRtn = Cntlr_CommCallback;
    pSubObj->callBkRtnParam = callbackArg;
#endif /* RTI_NDDS_4x */

    if (multicastIP == NULL)
       pSubObj->MulticastSubIP[0] = 0;   /* use UNICAST */
    else
       strcpy(pSubObj->MulticastSubIP,multicastIP);

#ifdef RTI_NDDS_4x
    initSubscription(pSubObj);
    attachOnDataAvailableCallback(pSubObj,Cntlr_CommCallback,callbackArg /* user data */ );
#endif /* RTI_NDDS_4x */
    createSubscription(pSubObj);
    return pSubObj;
}

#ifdef  RTI_NDDS_4x
/* Register an instance based on key given */
int Register_CntlrCommkeyed_instance(NDDS_ID pNDDS_Obj,int key)
{
    // DDS_InstanceHandle_t regHandle;
    Cntlr_Comm *pIssue = NULL;
    Cntlr_CommDataWriter *CntlrCommWriter = NULL;

    CntlrCommWriter = Cntlr_CommDataWriter_narrow(pNDDS_Obj->pDWriter);
    if (CntlrCommWriter == NULL) {
        errLogRet(LOGIT,debugInfo, "Register_CntlrCommkeyed_instance: DataReader narrow error.\n");
        return -1;
    }

    pIssue = pNDDS_Obj->instance;

    pIssue->key = key;

    // for Keyed Topics must register this keyed topic
    pNDDS_Obj->issueRegHandle = Cntlr_CommDataWriter_register_instance(CntlrCommWriter, pIssue);

    return 0;
}
#endif  /*  RTI_NDDS_4x */

/*
 * The Master via NDDS uses this callback function to create Subscriptions to the
 * Controller's Publications aimed at the Master Nexus
 *
 *					Author Greg Brissey 4-26-04
 */
#ifndef RTI_NDDS_4x
NDDSSubscription Cntlr_CommPatternSubCreate( const char *nddsTopic, const char *nddsType,
                  void *callBackRtnParam)
{
     NDDSSubscription pSub;

     DPRINT4(+1,"Cntlr_CommPatternSubCreate(): pCntrlSubs[%d]: Topic: '%s', Type: '%s', arg: 0x%lx\n",numCntrlSubs,
		nddsTopic, nddsType, callBackRtnParam);
     DPRINT2(+1,"callbackParam: 0x%lx, callBackRtnParam: 0x%lx\n",&callbackParam,callBackRtnParam);
     if (numCntrlSubs >= MAX_NEXUS_SUBS)
     {
        NDDS_ID pCntrlSub;
        errLogRet(LOGIT,debugInfo,"Number of controller subscriptions to master nexus has exceeded max: %d\n",MAX_NEXUS_SUBS);
	/* go ahead and make subscription, at this point we don't actually use the pCntrlSubs[] array for anything */
        pCntrlSub = createCntlrCommSub(NDDS_Domain, (char*) nddsTopic, NULL, (void *) &callbackParam );
        pSub = pCntrlSub->subscription;
        return pSub;
     }
     pCntrlSubs[numCntrlSubs]  = createCntlrCommSub(NDDS_Domain, (char*) nddsTopic, NULL, (void *) &callbackParam );
     pSub = pCntrlSubs[numCntrlSubs++]->subscription;
     return pSub;
}

/*
 *  Master creates a pattern subscriber, to dynamicly allow subscription creation
 *  as controllers come on-line and publusion to the Masters Nexus
 *
 *					Author Greg Brissey 4-26-04
 */
cntlrPubPatternSub()
{
    /* MASTER_SUB_COMM_PATTERN_TOPIC_STR */
    CntlrSubscriber = NddsSubscriberCreate(0);

    /* master subscribe to any publications from controllers */
    NddsSubscriberPatternAdd(CntlrSubscriber,
           "*/master/cmd",  Cntlr_CommNDDSType , Cntlr_CommPatternSubCreate, (void *)callbackParam);
}

#endif /* RTI_NDDS_4x */

initialMasterComm()
{
    InitCntlrStates();
    cntlrStatesAdd(hostName,CNTLR_READYnIDLE,MASTER_CONFIG_STD);
#ifndef RTI_NDDS_4x
    pCntlrPub = createCntlrCommPub(NDDS_Domain,MASTER_PUB_COMM_TOPIC_FORMAT_STR, "master1" );
    cntlrPubPatternSub();
#else
    long key;
    pCntlrPub = createCntlrCommPub(NDDS_Domain,MASTER_PUB_COMM_TOPIC_FORMAT_STR, "master1" );
    key = (BrdType << 8) | BrdNum;   /* key needs to be unique per board send to master */
    Register_CntlrCommkeyed_instance(pCntlrPub,key);
    /* in 4x all cntlrs publish on one topic to master (m21 - many two one) */
    pCntlrSub = createCntlrCommSub(NDDS_Domain,MASTER_SUB_COMM_M21TOPIC_FORMAT_STR,NULL, (void *) &masterCallbackParam );
#endif  /* RTI_NDDS_4x */
}

initialCntlrComm(const char* cntlrId, long brdType, long brdNum)
{
#ifndef RTI_NDDS_4x
    char topicStr[128];
    sprintf(topicStr,CNTLR_PUB_COMM_TOPIC_FORMAT_STR,cntlrId);
    pCntlrPub = createCntlrCommPub(NDDS_Domain,topicStr, cntlrId);
    callbackParam = 1;
    pCntlrSub = createCntlrCommSub(NDDS_Domain,CNTLR_SUB_COMM_TOPIC_FORMAT_STR, CNTLR_COMM_MULTICAST_IP,
				   (void *) &callbackParam);
#else
    long key;
    /* in 4x all the cntlr use the same topic to publish to master, an instance key is used */
    pCntlrPub = createCntlrCommPub(NDDS_Domain,CNTLR_PUB_COMM_M21TOPIC_FORMAT_STR, cntlrId );
    key = (brdType << 8) | brdNum;   /* key needs to be unique per board send to master */
    Register_CntlrCommkeyed_instance(pCntlrPub,key);
    pCntlrSub = createCntlrCommSub(NDDS_Domain,CNTLR_SUB_COMM_TOPIC_FORMAT_STR, CNTLR_COMM_MULTICAST_IP,
				   (void *) &cntlrCallbackParam);
    callbackParam = 1;
#endif  /* RTI_NDDS_4x */
}

/* =================================================================================== */
/* =================================================================================== */
/* ++++++++++++++++++++++++++  Exception Pub/Sun Routines +++++++++++++++++++++++++++++ */
/* =================================================================================== */
/* =================================================================================== */

typedef void (*PVF_MSG) (Cntlr_Comm *issue);

/*
 *   The NDDS callback routine, the routine is call when an issue of the subscribed topic
 *   is delivered.
 *   called with the context of the NDDS task n_rtu7400
 *
 */
#ifndef RTI_NDDS_4x
RTIBool Exception_CommCallback(const NDDSRecvInfo *issue, NDDSInstance *instance,
                             void *callBackRtnParam)
{
    Cntlr_Comm *recvIssue;
    PVF_MSG callbackFunc;

    if (issue->status == NDDS_FRESH_DATA)
    {
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_RECVEXCPT,NULL,NULL);
#endif
        recvIssue = (Cntlr_Comm *) instance;
        callbackFunc = (PVF_MSG) callBackRtnParam;
        DPRINT5(+1,"Exception_Comm CallBack:  cmd: %d, arg1: %d, arg2: %d, arg3: %d, crc: 0x%lx\n",
        recvIssue->cmd,recvIssue->arg1, recvIssue->arg2, recvIssue->arg3, recvIssue->crc32chksum);
        (*callbackFunc)(recvIssue);
#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_RECVEXCPT_CMPLT,NULL,NULL);
#endif
    }
   return RTI_TRUE;
}

#else /* RTI_NDDS_4x */

void Exception_CommCallback(void* listener_data, DDS_DataReader* reader)
{
   Cntlr_Comm *recvIssue;
   struct DDS_SampleInfo* info = NULL;
   struct DDS_SampleInfoSeq info_seq = DDS_SEQUENCE_INITIALIZER;
   DDS_ReturnCode_t retcode;
   DDS_Boolean result;
   long i,numIssues;
   void MasterNexus(Cntlr_Comm *issue);
   void CntlrPlexus(Cntlr_Comm *issue);
   int *param;
   PVF_MSG callbackFunc;
   DDS_TopicDescription *topicDesc;

   struct Cntlr_CommSeq data_seq = DDS_SEQUENCE_INITIALIZER;
   Cntlr_CommDataReader *CntlrComm_reader = NULL;

   CntlrComm_reader = Cntlr_CommDataReader_narrow(pExceptionSub->pDReader);
   if ( CntlrComm_reader == NULL)
   {
        errLogRet(LOGIT,debugInfo,"DataReader narrow error\n");
        return;
   }

   topicDesc = DDS_DataReader_get_topicdescription(reader);
   DPRINT2(+1,"Exception_CommCallback: Type: '%s', Name: '%s'\n",
      DDS_TopicDescription_get_type_name(topicDesc), DDS_TopicDescription_get_name(topicDesc));

   while(1)
   {

        // Given DDS_HANDLE_NIL as a parameter, take_next_instance returns
        // a sequence containing samples from only the next (in a well-determined
        // but unspecified order) un-taken instance.
        retcode =  Cntlr_CommDataReader_take_next_instance(
             CntlrComm_reader,
             &data_seq, &info_seq, DDS_LENGTH_UNLIMITED,
             &DDS_HANDLE_NIL,
             DDS_ANY_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

        // retcode = Cntlr_CommDataReader_take(CntlrComm_reader,
        //                       &data_seq, &info_seq,
        //                       DDS_LENGTH_UNLIMITED, DDS_ANY_SAMPLE_STATE,
        //                       DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE);

        if (retcode == DDS_RETCODE_NO_DATA) {
                 return; // break; // return;
        } else if (retcode != DDS_RETCODE_OK) {
                 errLogRet(LOGIT,debugInfo,"next instance error %d\n",retcode);
                 return; // break; // return;
        }

        numIssues = Cntlr_CommSeq_get_length(&data_seq);
        DPRINT1(+1,"Exception Cntlr_Comm CallBack: numIssues: %d\n",numIssues);

        for (i=0; i < numIssues; i++)
        {
           info = DDS_SampleInfoSeq_get_reference(&info_seq, i);
           if (info->valid_data)
           {
#ifdef INSTRUMENT
	      wvEvent(EVENT_NEXUS_RECVEXCPT,NULL,NULL);
#endif

              recvIssue = (Cntlr_Comm *) Cntlr_CommSeq_get_reference(&data_seq,i);
              callbackFunc = (PVF_MSG) listener_data;
              DPRINT2(+1,"Exception_Comm CallBack: Key: %d, Cntlr: '%s'\n",recvIssue->key,recvIssue->cntlrId);
              DPRINT5(+1,"Exception_Comm CallBack:  cmd: %d, arg1: %d, arg2: %d, arg3: %d, crc: 0x%lx\n",
                    recvIssue->cmd,recvIssue->arg1, recvIssue->arg2, recvIssue->arg3, recvIssue->crc32chksum);
              (*callbackFunc)(recvIssue);   // call function

#ifdef INSTRUMENT
	     wvEvent(EVENT_NEXUS_RECVEXCPT_CMPLT,NULL,NULL);
#endif
           }
        }
        retcode = Cntlr_CommDataReader_return_loan( CntlrComm_reader,
                  &data_seq, &info_seq);
        DDS_SampleInfoSeq_set_maximum(&info_seq, 0);
   } // while
   return;
}
#endif /* RTI_NDDS_4x */

/*
 * Create a Exception Publication to communicate with the Cntrollers/Master
 *
 *					Author Greg Brissey 4-26-04
 */
NDDS_ID createExceptionCommPub(NDDS_ID nddsId, char *topic, char *cntlrName)
{
    int result;
    NDDS_ID pPubObj;
    char pubtopic[128];
    Cntlr_Comm  *issue;

    /* Build Data type Object for both publication and subscription to Expproc */
    /* ------- malloc space for data type object --------- */
    if ( (pPubObj = (NDDS_ID) malloc( sizeof(NDDS_OBJ)) ) == NULL )
        return NULL;

    /* create the pub issue  Mutual Exclusion semaphore */
    pExceptionPubMutex = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE |
				    SEM_DELETE_SAFE);

    /* zero out structure */
    memset(pPubObj,0,sizeof(NDDS_OBJ));
    memcpy(pPubObj,nddsId,sizeof(NDDS_OBJ));

    strcpy(pPubObj->topicName,topic);
    pPubObj->pubThreadId = 5;  /* DEFAULT_PUB_THREADID; taskIdSelf(); */

    /* fills in dataTypeName, TypeRegisterFunc, TypeAllocFunc, TypeSizeFunc */
    getCntlr_CommInfo(pPubObj);

    DPRINT2(-1,"createExceptionCommPub: '%s' for Cntlr: '%s'\n",pPubObj->topicName,cntlrName);

#ifdef RTI_NDDS_4x
  #ifdef PFG_LOCK_COMBO_CNTLR // has more readers/writers than single-function controllers
     pPubObj->queueSize  = 4;
     pPubObj->highWaterMark = 2;
     pPubObj->AckRequestsPerSendQueue = 4;
  #else
     pPubObj->queueSize  = 2;
     pPubObj->highWaterMark = 1;
     pPubObj->AckRequestsPerSendQueue = 2;
  #endif
     pPubObj->lowWaterMark =  0;
     initPublication(pPubObj);
#endif /* RTI_NDDS_4x */

    createPublication(pPubObj);
    issue = (Cntlr_Comm  *) pPubObj->instance;
    strcpy(issue->cntlrId,cntlrName);   /* fill in the constant cntlrId string */
    return(pPubObj);
}

/*
 * Create a Exception Subscription to communicate with the Controllers/Master
 *
 *					Author Greg Brissey 4-26-04
 */
NDDS_ID createExceptionCommSub(NDDS_ID nddsId, char *topic, char *multicastIP, void *callbackArg)
{
    NDDS_ID  pSubObj;
    char subtopic[128];

    /* Build Data type Object for both publication and subscription to Expproc */
    /* ------- malloc space for data type object --------- */
    if ( (pSubObj = (NDDS_ID) malloc( sizeof(NDDS_OBJ)) ) == NULL )
    {
        return(NULL);
    }

    /* zero out structure */
    memset(pSubObj,0,sizeof(NDDS_OBJ));
    memcpy(pSubObj,nddsId,sizeof(NDDS_OBJ));

    strcpy(pSubObj->topicName,topic);

    /* fills in dataTypeName, TypeRegisterFunc, TypeAllocFunc, TypeSizeFunc */
    getCntlr_CommInfo(pSubObj);

#ifndef RTI_NDDS_4x
    pSubObj->callBkRtn = Exception_CommCallback;
    pSubObj->callBkRtnParam = callbackArg;  /* this is actually a callback routine */
#endif /* RTI_NDDS_4x */

    if (multicastIP == NULL)
       pSubObj->MulticastSubIP[0] = 0;   /* use UNICAST */
    else
       strcpy(pSubObj->MulticastSubIP,multicastIP);

#ifdef RTI_NDDS_4x

    initSubscription(pSubObj);
    attachOnDataAvailableCallback(pSubObj,Exception_CommCallback,callbackArg /* user callback func */ );
#endif /* RTI_NDDS_4x */

    createSubscription(pSubObj);
    return ( pSubObj );
}

void initialExceptionComm(void *callbackFunc)
{
    long key;

    startLedPatShow();  // as soon as possible

    // DPRINT(-5,"createExceptionCommPub\n");
    pExceptionPub = createExceptionCommPub(NDDS_Domain,EXCEPTION_PUB_COMM_TOPIC_FORMAT_STR, hostName );
#ifdef RTI_NDDS_4x
    key = (BrdType << 8) | BrdNum;   /* key needs to be unique per board send to master */
    Register_CntlrCommkeyed_instance(pExceptionPub,key);
#endif /* RTI_NDDS_4x */
    // DPRINT(-5,"createExceptionCommSub\n");
    pExceptionSub = createExceptionCommSub(NDDS_Domain,EXCEPTION_SUB_COMM_TOPIC_FORMAT_STR, EXCEPTION_COMM_MULTICAST_IP,
				   (void *) callbackFunc);
}

/*
 * Used by All , to publish warnings or errors
 * A mulitcast publication thus all controllers will get this pub
 * even the one sending it
 *
 */
int sendException(int cmd, int arg1,int arg2,int arg3,char *strmsg)
{
#ifdef RTI_NDDS_4x
   DDS_ReturnCode_t result;
   DDS_InstanceHandle_t instance_handle = DDS_HANDLE_NIL;
   Cntlr_CommDataWriter *CntlrCmd_writer = NULL;
#endif /* RTI_NDDS_4x */
   Cntlr_Comm *issue;

#ifdef INSTRUMENT
	wvEvent(EVENT_NEXUS_SENDEXCPT,NULL,NULL);
#endif
   /* if it's a warning then don't bother with updating the cntlrState
    * since could prevent proper operation, observed failure was master wait for controllers to
    * report ready for sync, however after the grad1 reported ready for sync but others had not, the grad sent
    * a warning which changed its state thus the master never stated the FIFO, since the grad state had changed
    *       Greg Brissey   10/26/05
    */
   DPRINT1(+1,"sendException: callbackParam = %d\n",callbackParam);
   if ( arg1 > 200)   /* if errocde is a warning do NOT update cntlr state */
   {

     if (callbackParam == 0)   /* Master */
     {
      cntlrSetState("master1",CNTLR_EXCPT_INITIATED,arg1 /* errorcode */);
      DPRINT(+2,"sendException: master1 CNTLR_EXCPT_INITIATED\n");
     }
     else
     {
      send2Master(CNTLR_CMD_STATE_UPDATE,CNTLR_EXCPT_INITIATED, arg1 /* errorcode */, 0,NULL);
      DPRINT(+2,"sendException: Send master CNTLR_EXCPT_INITIATED\n");
     }
   }

   issue = pExceptionPub->instance;
   semTake(pExceptionPubMutex, WAIT_FOREVER);
   DPRINT(+1,"sendException: got Mutex\n");
   issue->cmd  = cmd;  /* atoi( token ); */
   issue->errorcode = arg1;
   issue->warningcode = arg2;
   issue->arg1 = arg3;

   if (strmsg != NULL)
     {
       int strsize = strlen(strmsg);
       if (strsize <= COMM_MAX_STR_SIZE)
	 strncpy(issue->msgstr,strmsg,COMM_MAX_STR_SIZE);
       else
	 errLogRet(LOGIT,debugInfo,"sendException: msg to long: %d, max: %d\n",strsize,COMM_MAX_STR_SIZE);
     }
   DPRINT(+2,"sendException: sendExceptionDirectly\n");
   sendExceptionDirectly(issue);  /* send the exception directly to the phandler of the controller */

#ifndef RTI_NDDS_4x
   nddsPublishData(pExceptionPub); /* send exception to other controllers via NDDS publication */
#else  /* RTI_NDDS_4x */
   CntlrCmd_writer = Cntlr_CommDataWriter_narrow(pExceptionPub->pDWriter);
   if (CntlrCmd_writer == NULL) {
     errLogRet(LOGIT,debugInfo,"DataWriter narrow error\n");
     semGive(pExceptionPubMutex);
     return -1;
   }

   DPRINT(+2,"sendException: pub 4x exception\n");
   result = Cntlr_CommDataWriter_write(CntlrCmd_writer,
				       issue,&instance_handle);
   if (result != DDS_RETCODE_OK) {
     errLogRet(LOGIT,debugInfo,"DataWriter write error: %d\n",result);
   }
#endif /* RTI_NDDS_4x */

   DPRINT(+1,"sendExcpetion: give Mutex\n");
   semGive(pExceptionPubMutex);

   if (cmd != WARNING_MSG)
     patternType = 1;   /* show execption pattern on panel LEDs */

#ifdef INSTRUMENT
   wvEvent(EVENT_NEXUS_SENDEXCPT_CMPLT,NULL,NULL);
#endif
   return 0;
}

prtcallbackParm()
{
   DPRINT1(-6,"sendException: callbackParam = %d, 0 == Master\n",callbackParam);
}
/*
 * diagnostic stubs, for easy testing
 *
 *					Author Greg Brissey 4-26-04
 */
int rollcall()
{
    cntlrCommPub(CNTLR_CMD_ROLLCALL,0,0,0,NULL);
    return 0;
}

here()
{
    cntlrCommPub(CNTLR_CMD_HERE,0,0,0,NULL);
}

sndstate(int state)
{
    send2Master(CNTLR_CMD_STATE_UPDATE,state,0,0,NULL);
}

static void callbackF(Cntlr_Comm *recvIssue)
{
   DPRINT5(-1,"Exception_Comm CallBack:  cmd: %d, arg1: %d, arg2: %d, arg3: %d, crc: 0x%lx\n",
        recvIssue->cmd,recvIssue->arg1, recvIssue->arg2, recvIssue->arg3, recvIssue->crc32chksum);
}
regexcp()
{
   initialExceptionComm((void *)callbackF);
}
pubExcp(int cmd)
{
   sendException(cmd, 1, 2, 3,"testing");
}

sndErr()
{
   /* HARD_ERROR    15, HDWAREERROR     900, TOOFEWRCVRS     22 */
   /* sendException(HARD_ERROR, HDWAREERROR + TOOFEWRCVRS, 0,0,NULL); */
   sendException(15, 922, 0, 0, NULL);
}
sndWarn()
{
   /* WARING_MSG  14, WARNING     100, ADCOVR     3 */
   /* sendException(HARD_ERROR, HDWAREERROR + TOOFEWRCVRS, 0,0,NULL); */
   sendException(14, 116, 0, 0, NULL);
}

SEM_ID pTheShowSem;
SEM_ID pTheShowMutex;

static int patternStpFlag = 0;

int haltLedShow()
{
    semTake(pTheShowMutex,60);    /* Mutex */
       patternStpFlag = 1;
    semGive(pTheShowMutex);    /* give Mutex back */
    return 0;
}

int resumeLedShow()
{
    semTake(pTheShowMutex,60);    /* Mutex */
      semGive(pTheShowSem);    /* taken once exp start, etc. */
      patternStpFlag = 0;
    semGive(pTheShowMutex);    /* give Mutex back */
   return 0;
}

PatternShow()
{
   while(1)
   {
      semTake(pTheShowSem,WAIT_FOREVER);    /* taken once exp start, etc. */
      switch(patternType)
      {
          case 0 /* IDLE_PAT */:
               idlepat(calcSysClkTicks(50), calcSysClkTicks(67));  /* idlepat(3,4);    */
               break;
          case 1 /* EXCEPT_PAT */:
	       exceptpat(calcSysClkTicks(117));   /* exceptpat(7); */
               break;
           default:
               idlepat(calcSysClkTicks(50), calcSysClkTicks(67)); /* idlepat(3,4);    */
               break;
      }
      semGive(pTheShowSem);    /* taken once exp start, etc. */
      if (patternStpFlag == 1)
      {
         semTake(pTheShowSem,60);    /* taken once exp start, etc. */
         panelLedAllOff();
         patternStpFlag = 0;
      }
   }
}

idlepat(int ondelay,int offdelay)
{
    panelLedMaskOn(0x20);
    taskDelay(ondelay);
    panelLedMaskOn(0x10);
    taskDelay(ondelay);
    panelLedMaskOn(0x08);
    taskDelay(ondelay);
    panelLedMaskOn(0x04);
    taskDelay(ondelay);
    panelLedMaskOn(0x02);
    taskDelay(ondelay);
    panelLedMaskOff(0x20);
    taskDelay(offdelay);
    panelLedMaskOff(0x10);
    taskDelay(offdelay);
    panelLedMaskOff(0x08);
    taskDelay(offdelay);
    panelLedMaskOff(0x04);
    taskDelay(offdelay);
    panelLedMaskOn(0x04);
    taskDelay(ondelay);
    panelLedMaskOn(0x08);
    taskDelay(ondelay);
    panelLedMaskOn(0x10);
    taskDelay(ondelay);
    panelLedMaskOn(0x20);
    panelLedMaskOff(0x02);
    taskDelay(offdelay);
    panelLedMaskOff(0x04);
    taskDelay(offdelay);
    panelLedMaskOff(0x08);
    taskDelay(offdelay);
    panelLedMaskOff(0x10);
    taskDelay(offdelay);
}

exceptpat(int delay)
{
    panelLedMaskOn(0x22);
    taskDelay(delay);
    panelLedMaskOff(0x22);
    panelLedMaskOn(0x14);
    taskDelay(delay);
    panelLedMaskOff(0x14);
    panelLedOn(4);
    taskDelay(delay);
    panelLedMaskOn(0x14);
    taskDelay(delay);
    panelLedOff(4);
    panelLedMaskOff(0x14);
}

/* priority = 255  */
/* startLedPatShow(int taskpriority,int taskoptions,int stacksize) */
startLedPatShow()
{
     /* PANEL_LED_TASK_PRIORITY=255, STD_STACKSIZE=4096, STD_TASKOPTIONS=0 */
    pTheShowSem = semBCreate(SEM_Q_FIFO,SEM_FULL);
    pTheShowMutex = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE |
                                  SEM_DELETE_SAFE);

    if (taskNameToId("tPanelLeds") == ERROR)
      taskSpawn("tPanelLeds",PANEL_LED_TASK_PRIORITY,STD_TASKOPTIONS,
                   STD_STACKSIZE,PatternShow, 1,2,3,4,5,6,7,8,9,10);
}


text:
package org.apache.isis.objectstore.jdo.datanucleus.service.eventbus;

import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.core.runtime.services.eventbus.EventBusServiceDefault;
import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis.Hint;

/**
 * This domain service that enables both the framework and application code to publish events through either a
 * Guava {@link com.google.common.eventbus.EventBus} instance or through an Axon
 * {@link org.axonframework.eventhandling.SimpleEventBus} instance.

 *
 *

 * In addition, this implementation is "JDO-aware" meaning that it allows events to be
 * {@link #post(Object) posted} from the setters of entities, automatically ignoring any calls to those setters that
 * occur as a side-effect of the JDO load/detach lifecycle.
 *
 *

 * This implementation has no UI and there are no other implementations of the service API, and so it is annotated
 * with {@link org.apache.isis.applib.annotation.DomainService}.  Because it is implemented in the core, this means
 * that it is automatically registered and available for use; no further configuration is required.
 */
@DomainService(
        nature = NatureOfService.DOMAIN,
        menuOrder = "0" // initialize first, so available for any services that persist objects in their @PostConstruct
)
public class EventBusServiceJdo extends EventBusServiceDefault {

    /**
     * skip if called in any way by way of the {@link JDOStateManagerForIsis}.
     *
     *

     * The {@link JDOStateManagerForIsis} sets a {@link JDOStateManagerForIsis#hint threadlocal}
     * if it has been called.
     */
    @Programmatic
    @Override
    protected boolean skip(Object event) {
        return JDOStateManagerForIsis.hint.get() != Hint.NONE;
    }

}


text:
<!DOCTYPE HTML>
>

	<title>My PR</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

		Header

Welcome  to my-pr

This application allows you to register yours Personal Records.


text:
require 'lib/bun/file/descriptor'
require 'lib/string'
require 'yaml'
require 'date'
require 'tmpdir'

module Bun

  class File < ::File

    class BadFileFormat < RuntimeError; end
    class BadBlockError < RuntimeError; end
    class ReadError < ArgumentError; end

    class << self

      @@stdin_cache = nil  # Content of STDIN (we cache it, to allow rereading)
      @@last_read = nil    # Name of the last file read, except STDIN (we save it, to avoid rereading)
      @@last_content = nil # Content of the last file read (except STDIN)
      @@messages = {}

      def messages
        @@messages
      end

      def clear_messages(path=nil)
        if path
          path = ::File.expand_path(path)
          @@messages[path] = []
        else
          @@messages = {}
        end
      end

      def add_message(path,msg=nil)
        case msg
        when nil
          # Do nothing
        when Array
          msg.each {|m| add_msg(path, m)}
        else
          path = ::File.expand_path(path)
          @@messages[path] ||= []
          @@messages[path] << msg
        end
      end
      alias_method :add_messages, :add_message

      def replace_messages(path=nil,msg=nil)
        clear_messages(path)
        add_message path,msg
      end

      def all_messages(path=nil)
        if path
          path = ::File.expand_path(path)
          @@messages[path] || []
        else
          @@messages.keys.sort.map {|path| @@messages[path]}.flatten
        end
      end

      def message_count(path=nil)
        if path
          path = ::File.expand_path(path)
          (@@messages[path]||[]).size
        else
          @@messages.values.map{|msgs| msgs.size}.sum
        end
      end

      def warn_messages(path=nil)
        return if message_count(path)==0
        all_messages(path).each {|msg| warn msg}
      end

      # Allows STDIN to be read multiple times
      def read(*args)
        options = args.last.is_a?(Hash) ? args.pop : {}
        path = args.shift
        text = if path == '-'
          Bun.cache(:read_stdin, :stdin) { $stdin.read.force_encoding('ascii-8bit') }
        else
          Bun.cache(:read_path, File.expand_path(path)) do
            stop "!File #{path} does not exist" unless File.exists?(path)
            Bun.cache(:read_path, path) do
              (::File.read(path) || '').force_encoding('ascii-8bit') # We cache entire file
            end
          end
        end
        case args.size
        when 0
          # Do nothing
        when 1 # Read length specified
          raise ReadError, "Unable to handle read parameter #{args[0].inspect}" unless args[0].is_a?(Numeric)
          text = text[0,args[0]]
        when 2 # Read length and offset specified
          raise ReadError, "Unable to handle first read parameter #{args[0].inspect}" unless args[0].is_a?(Numeric)
          raise ReadError, "Unable to handle second read parameter #{args[1].inspect}" unless args[1].is_a?(Numeric)
          text = text[args[1], args[0]]
        else
          raise ReadError, "Unable to handle first read parameters #{args.inspect}"
        end
        text
      end

      def relative_path(*f)
        options = {}
        if f.last.is_a?(Hash)
          options = f.pop
        end
        relative_to = options[:relative_to] || ENV['HOME']
        File.expand_path(File.join(*f), relative_to).sub(/^#{Regexp.escape(relative_to)}\//,'')
      end

      def temporary_file_name(seed)
        Dir::Tmpname.make_tmpname [Dir::Tmpname.tmpdir, seed], nil
      end

      def temporary_file(seed, options={}, &blk)
        file = Tempfile.new(seed)
        return file unless block_given?
        begin
          yield(file)
        ensure
          file.close unless options[:keep]
        end
      end

      def temporary_directory(seed, options={}, &blk)
        directory_name = Dir.mktmpdir(seed)
        return directory_name unless block_given?
        begin
          yield(directory_name)
        ensure
          Dir.rmdir(directory_name) unless options[:keep]
        end
      end

      # def control_character_counts(path)
      #   Bun.readfile(path).control_character_counts
      # end

      def baked_file_and_data(path, options={})
        if options[:promote]
          if File.format(path) == :baked
            [nil, read(path)]
          elsif File.type(path) == :frozen && !options[:shard]
            files = File::Decoded.open(path, :promote=>true, :expand=>true)
            data = Bun.cache(:baked_expanded_data, File.expand_path(path)) { files.values.map{|f| f.data}.join }
            [files.values.first, data]
          else
            f = File::Decoded.open(path, :promote=>true, :shard=>options[:shard])
            data = Bun.cache(:baked_unexpanded_data, [File.expand_path(path), options[:shard]]) { f.data }
            [f, data]
          end
        else
          [nil, read(path)]
        end
      end

      def file_for_expression(path, options={})
        case File.format(path)
        when :packed, :unpacked
          f = if options[:promote]
            File::Unpacked.open(path, :promote=>true)
          else
            File::Packed.open(path)
          end
          merge_shard_descriptor(f, options[:shard]) if options[:shard]
          f
        else
          File.open(path)
        end
      end

      def merge_shard_descriptor(f, shard)
        shard_entry = f.descriptor.shards[shard]
        shard_entry.keys.each do |key|
          new_key = "shard_#{key}".to_sym
          f.descriptor.merge!(new_key=>shard_entry[key])
        end
        f.descriptor.delete(:shards)
        f.descriptor.delete('shards')
      end

      def baked_data(path, options={})
        _, data = baked_file_and_data(path, options)
        data
      end

      def trait(file, trait, options={})
        Bun::File.create_expression(file, trait,
          promote: options[:promote], shard: options[:shard], raise: options[:raise])
      end

      def create_examination(path, analysis, options={})
        examiner = String::Trait.create(analysis, options)
        examiner.attach(:string) { baked_data(path, options) } # Lazy evaluation of file contents
        examiner.attach(:file, self)
        examiner
      end
      protected :create_examination

      def create_expression(path, expression, options={})
        expression_options = options.merge(expression: expression, path: path, raise: options[:raise])
        evaluator = Bun::Expression.new(expression_options)
        evaluator.attach(:file) { file_for_expression(path, options) }
        evaluator.attach(:data) { baked_data(path, options) }
        evaluator
      end
      protected :create_expression

      def binary?(path)
        prefix = File.read(path, 4)
        prefix != "---\n" # YAML prefix; one of the unpacked formats
      end

      def nonpacked?(path)
        prefix = File.read(path, 21)
        prefix == "---\n:identifier: Bun\n" # YAML prefix with identifier
      end

      PACKED_FILE_SIGNATURE = "\x0\x0\x40" # Packed files always start with this

      def index_file_for(path)
        dir = File.dirname(path)
        path = File.basename(path)
        loop do
          index_file_path = File.join(dir, Bun::DEFAULT_BAKED_INDEX_DIRECTORY, path+Bun::INDEX_FILE_EXTENSION)
          return index_file_path if File.exists?(index_file_path)
          break if dir == "/" || dir == "."
          path = File.join(File.basename(dir), path)
          dir = File.dirname(dir)
        end
        nil
      end

      def packed?(path)
        return false if nonpacked?(path)
        if File.read(path, PACKED_FILE_SIGNATURE.size).force_encoding('ascii-8bit') == PACKED_FILE_SIGNATURE
          res = begin
            File::Packed.open(path, force: true)
          rescue => e
            false
          end
          index_file_for(path) ? false : res # If .INDEX... exists, then it's baked, not packed
        else
          false
        end
      end

      def open(path, options={}, &blk)
        # TODO But format opens and reads the file, too...
        case fmt = format(path)
        when :packed
          File::Packed.open(path, options, &blk)
        when :unpacked, :cataloged
          File::Unpacked.open(path, options, &blk)
        when :decoded
          File::Decoded.open(path, options, &blk)
        when :baked
          File::Baked.open(path, &blk)
        else
          # TODO Why not?
          raise BadFileFormat, "Can't open file of this format: #{fmt.inspect}"
        end
      end

      def type(path)
        # return :packed if packed?(path)
        begin
          f = File::Unpacked.open(path, promote: true)
          f.type
        rescue
          raise
          :unknown
        end
      end

      def format(path)
        res = if packed?(path)
          :packed
        elsif binary?(path)
          :baked
        else
          d = File::Unpacked.build_descriptor_from_file(path)
          d.format
        end
        res
      end

      def format_level(fmt)
        [:packed, :unpacked, :decoded, :baked].index(fmt)
      end

      def file_outgrades?(path, level)
        format_level(format(path)) > format_level(level)
      end

      def descriptor(path, options={})
        # TODO This is smelly (but necessary, in case the file was opened with :force)
        open(path, :force=>true) {|f| f.descriptor }
      rescue Errno::ENOENT => e
        return nil if options[:allow]
        raise
      end

      def timestamp(file)
        time = if directory?(file)
          leaves(file).map{|f| timestamp(f)}.min
        else
          descr = File::Unpacked.build_descriptor_from_file(file) rescue nil
          descr && descr.timestamp
        end
        time || Time.now
      end

      def leaves(path)
        Dir[join(path, '**', '*')].reject{|f| directory?(f)}
      end

      # Convert from packed format to unpacked (i.e. YAML)
      def unpack(path, to, options={})
        if File.exists?(to)
          unless options[:force]
            warn "Skipping unpack: #{to} already exists" unless options[:quiet]
            return
          end
        end
        case format(path)
        when :packed
          open(path) do |f|
            cvt = f.unpack(fix: options[:fix])
            cvt.descriptor.tape = options[:tape] if options[:tape]
            cvt.descriptor.merge!(:unpack_time=>Time.now, :unpacked_by=>Bun.expanded_version)
            cvt.write(to)
          end
        else
          Shell.new.cp(path, to)
        end
      end

      def decode(path, to, options={}, &blk)
        self.clear_messages
        case format(path)
        when :packed
          File::Unpacked.open(path, options.merge(promote: true)) do |f|
            f.decode(to, options, &blk)
          end
        else
          File.open(path, options) do |f|
            f.decode(to, options, &blk)
          end
        end
      end

      def bake(path, to, options={})
        scrub = options.delete(:scrub)
        case format(path)
        when :baked, :decoded
          File.open(path, options) {|f| f.bake(to, scrub: scrub, index: options[:index])}
        else
          File::Decoded.open(path, options.merge(promote: true)) {|f| f.bake(to, scrub: scrub, index: options[:index])}
        end
      end

      SCRUB_COLUMN_WIDTH = 60
      SCRUB_FORM_FEED    = %q{"\n" + "-"*column_width + "\n"}
      SCRUB_VERTICAL_TAB = %q{"\n"}

      def scrub(from, to, options={})
        column_width = options[:width] || SCRUB_COLUMN_WIDTH
        form_feed = options[:ff] || eval(SCRUB_FORM_FEED)
        vertical_tab = options[:vtab] || eval(SCRUB_VERTICAL_TAB)
        text = File.read(from)
        scrubbed_text = text.scrub(:column_width=>column_width, :form_feed=>form_feed, :vertical_tab=>vertical_tab)
        Shell.new.write(to, scrubbed_text)
      end

      def expand_path(path, relative_to=nil)
        path == '-' ? path : super(path, relative_to)
      end

      def get_shard(path)
        if path =~ /^(.*?)\[(.*)\]$/ # Has shard specifier
          [$1, $2]
        else
          [path, nil]
        end
      end

      def shards(file)
        File.open(file) {|f| f.descriptor.shards || [] }
      end

      def shard_names(file)
        shards(file).map {|shard| shard.name }
      end

      # Does this path (or any part of its directory structure) conflict with an existing file?
      def conflicts?(path, options={})
        return false if path.nil? # Signifies "no output"; therefore, no conflict
        return false if path=='-' # Signifies STDOUT; never a conflict
        return false if File.directory?(path) && options[:directories_okay]
        return path  if File.exists?(path)
        dir = File.dirname(path)
        return false if dir=='.' || dir=='/'
        return conflicts?(dir, directories_okay: true)
      end

      # Note: returns an array of files that conflict with a proposed new file f. The
      def conflicting_files(f)
        ext = File.nondate_extname(f)
        conflict_base = f.sub(/#{Regexp.escape(ext)}$/,'')
        pat = /^#{Regexp.escape(conflict_base)}(?:\.V\d+)?#{Regexp.escape(ext)}$/
        Dir.glob(conflict_base+'*')
           .select {|file| file =~ pat }
      end

      def nondate_extname(path)
        ext = File.extname(path)
        ext = "" if ext =~ /^\.\d{4}(?:_\d{8})?(?:_\d{6})?$/ # Date suffix doesn't count as an extension
        ext
      end

      def directory_count(path)
        Dir[join(path, '*')].size
      end

      def path_heirarchy(path)
        case path.to_s
        when ""
          return []
        when ".", "/"
          return [path]
        end
        return path_heirarchy(dirname(path)) + [path]
      end

      def ancestor_directories(path)
        h = path_heirarchy(path)
        h.pop
        h
      end

      # Create a set of moves that will merge a set of files to a destination without conflicts.
      # Where necessary, add version numbers to the files to avoid stomping any file
      #
      # This method returns an array of moves that avoids conflicts. Each element in the array is
      # a hash in the form {:from=>from_file, :to=>to_file, :version=>99}. The moves MUST be executed
      # in the order specified to guarantee avoiding conflicts!
      #
      # If there is no conflict, this method returns [{from: file, to: new_file, version: nil}]
      #
      # Rules for moving files
      #   1. a/b/c/d (without extension) moves to a/b/c/d.v1 (but see below)
      #   2. a/b/c/d...y.ext (with extension) moves to a/b/c/d...y.v99.ext (but see below)
      #   3. a/b/c/d...v3.ext doesn't move
      #   4. Version numbers are always assigned in ascending order of file date
      #
      # Arguments:
      #   files is an array of (fully qualified) file names
      #   dest is the name of where you want to move them to.
      #
      # TODO More general pattern for version numbering
      def moves_to_merge(files, dest)
        case files.size
        when 0
          return []
        when 1
          return [] if files.first == dest
          return [{from: files.first, to: dest, version: nil}]
        end
        digits = files.size.to_s.size # How many digits in the version numbers?
        dest = re_version_file(dest, nil) # Remove .V999 from dest, if any
        version_count = 0
        unsorted_moves = files.map {|f| [f, File.timestamp(f)] } # Fetch file versions only once
             .sort_by {|f, timestamp| timestamp} # Sort oldest files first
             .map do |f, timestamp| # Reset versions in order by file date
                    version_count += 1
                    {from: f, version: version_count, to: re_version_file(dest, version_count, digits: digits)}
                  end
             .reject {|spec| spec[:from] == spec[:to]} # Remove any "no-op" moves
        # Calculate dependencies
        unsorted_moves.each.with_index do |move, i|
          move[:index] = i
          move[:depends_on] = []
        end
        unsorted_moves.each.with_index do |move, i|
          unsorted_moves.each do |move2|
            next if move2[:index]==move[:index]
            move[:depends_on] << move2[:index] \
              if move2[:from] == move[:to] || ancestor_directories(move2[:from]).include?(move[:from])
          end
        end
        unsorted_moves.topological_sort do |moves, i|
          move = moves[i]
          move[:depends_on].map {|ix| moves.find_index {|move2| move2[:index]==ix}}.compact
        end
      end

      def re_version_file(f, version, options={})
        digits = options[:digits] || 1
        f =~ /^(.*?)((?:\.V\d+)?)$/ # May already have a .v999 prefix
        version = version ? %Q{.V#{"%0#{digits}d" % version}} : ""
        "#{$1}#{version}"
      end

    end # File class methods

    attr_reader :archive
    attr_reader :tape_path

    attr_accessor :descriptor
    attr_accessor :errors
    attr_accessor :decoded
    attr_accessor :original_tape
    attr_accessor :original_tape_path

    def initialize(options={}, &blk)
      @tape = options[:tape]
      @tape_path = options[:tape_path]
      @size = options[:size]
      @archive = options[:archive]
      clear_errors
      yield(self) if block_given?
    end

    # private_class_method :new

    def clear_errors
      @errors = []
    end

    def error(err)
      @errors << err
    end

    def open_time
      return nil unless tape_path && File.exists?(tape_path)
      File.atime(tape_path)
    end

    def close
      # update_index
    end

    def read
      self.class.read(descriptor.tape_path)
    end

    def update_index
      return unless @archive
      @archive.update_index(:file=>self)
    end

    def tape
      @tape ||= File.basename(tape_path)
    end

    def path
      descriptor.path
    end

    def mark(tag_name, tag_value)
      descriptor.set_field(tag_name, tag_value, :user=>true) # Allow only unregistered field names
    end

    def updated
      descriptor.updated
    end

    def copy_descriptor(to, new_settings={})
      descriptor.copy(to, new_settings)
    end

    def media_codes
      []
    end

    def multi_segment
      false
    end

    def content_start
      0
    end
  end
end


text:
package net.geforcemods.securitycraft.blocks.reinforced;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.BeaconBeamBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;

public class ReinforcedStainedGlassBlock extends ReinforcedGlassBlock implements BeaconBeamBlock {
	private final DyeColor color;

	public ReinforcedStainedGlassBlock(Block.Properties properties, DyeColor color, Block vB) {
		super(properties, vB);
		this.color = color;
	}

	@Override
	public float[] getBeaconColorMultiplier(BlockState state, LevelReader level, BlockPos pos, BlockPos beaconPos) {
		return color.getTextureDiffuseColors();
	}

	@Override
	public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
		return true;
	}

	@Override
	public DyeColor getColor() {
		return color;
	}

	@Override
	public float getShadeBrightness(BlockState state, BlockGetter level, BlockPos pos) {
		return 1.0F;
	}

	@Override
	public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) {
		return adjacentBlockState.getBlock() == this ? true : super.skipRendering(state, adjacentBlockState, side);
	}
}