use same os_codename to generate Dockerfile for doc job

# generated from @template_name

FROM ubuntu:@os_code_name
MAINTAINER Dirk Thomas dthomas+buildfarm@@osrfoundation.org

VOLUME ["/var/cache/apt/archives"]

ENV DEBIAN_FRONTEND noninteractive
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV TZ @timezone

RUN useradd -u @uid -m buildfarm

@(TEMPLATE(
    'snippet/add_distribution_repositories.Dockerfile.em',
    distribution_repository_keys=distribution_repository_keys,
    distribution_repository_urls=distribution_repository_urls,
    os_code_name=os_code_name,
    add_source=False,
))@

@(TEMPLATE(
    'snippet/add_wrapper_scripts.Dockerfile.em',
    wrapper_scripts=wrapper_scripts,
))@

# automatic invalidation once every day
RUN echo "@today_str"

@(TEMPLATE(
    'snippet/install_python3.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@

RUN python3 -u /tmp/wrapper_scripts/apt-get.py update-and-install -q -y git mercurial python3-apt python3-catkin-pkg python3-empy python3-rosdep python3-rosdistro subversion

# always invalidate to actually have the latest apt and rosdep state
RUN echo "@now_str"
RUN python3 -u /tmp/wrapper_scripts/apt-get.py update

ENV ROSDISTRO_INDEX_URL @rosdistro_index_url
RUN rosdep init

USER buildfarm

ENTRYPOINT ["sh", "-c"]
@{
cmds = [
    'rosdep update',

    'PYTHONPATH=/tmp/ros_buildfarm:$PYTHONPATH python3 -u' + \
    ' /tmp/ros_buildfarm/scripts/doc/create_doc_task_generator.py' + \
    ' ' + config_url + \
    ' --rosdistro-name ' + rosdistro_name + \
    ' ' + doc_build_name + \
    ' --workspace-root /tmp/catkin_workspace' + \
    ' --rosdoc-lite-dir /tmp/rosdoc_lite' + \
    ' --catkin-sphinx-dir /tmp/catkin-sphinx' + \
    ' --rosdoc-index-dir /tmp/rosdoc_index' + \
    ' ' + repository_name + \
    ' --os-name ' + os_name + \
    ' --os-code-name ' + os_code_name + \
    ' --arch ' + arch + \
    ' --vcs-info "%s"' % vcs_info + \
    ' --distribution-repository-urls ' + ' '.join(distribution_repository_urls) + \
    ' --distribution-repository-key-files ' + ' ' .join(['/tmp/keys/%d.key' % i for i in range(len(distribution_repository_keys))]) + \
    (' --force' if force else '') + \
    ' --output-dir /tmp/generated_documentation' + \
    ' --dockerfile-dir /tmp/docker_doc',
]
}@
CMD ["@(' && '.join([c.replace('"', '\\"') for c in cmds]))"]

# generated from @template_name

FROM ubuntu:trusty
MAINTAINER Dirk Thomas dthomas+buildfarm@@osrfoundation.org

VOLUME ["/var/cache/apt/archives"]

ENV DEBIAN_FRONTEND noninteractive
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV TZ @timezone

RUN useradd -u @uid -m buildfarm

@(TEMPLATE(
    'snippet/add_distribution_repositories.Dockerfile.em',
    distribution_repository_keys=distribution_repository_keys,
    distribution_repository_urls=distribution_repository_urls,
    os_code_name='trusty',
    add_source=False,
))@

@(TEMPLATE(
    'snippet/add_wrapper_scripts.Dockerfile.em',
    wrapper_scripts=wrapper_scripts,
))@

# automatic invalidation once every day
RUN echo "@today_str"

RUN python3 -u /tmp/wrapper_scripts/apt-get.py update-and-install -q -y git mercurial python3-apt python3-catkin-pkg python3-empy python3-rosdep python3-rosdistro subversion

# always invalidate to actually have the latest apt and rosdep state
RUN echo "@now_str"
RUN python3 -u /tmp/wrapper_scripts/apt-get.py update

ENV ROSDISTRO_INDEX_URL @rosdistro_index_url
RUN rosdep init

USER buildfarm

ENTRYPOINT ["sh", "-c"]
@{
cmds = [
    'rosdep update',

    'PYTHONPATH=/tmp/ros_buildfarm:$PYTHONPATH python3 -u' + \
    ' /tmp/ros_buildfarm/scripts/doc/create_doc_task_generator.py' + \
    ' ' + config_url + \
    ' --rosdistro-name ' + rosdistro_name + \
    ' ' + doc_build_name + \
    ' --workspace-root /tmp/catkin_workspace' + \
    ' --rosdoc-lite-dir /tmp/rosdoc_lite' + \
    ' --catkin-sphinx-dir /tmp/catkin-sphinx' + \
    ' --rosdoc-index-dir /tmp/rosdoc_index' + \
    ' ' + repository_name + \
    ' --os-name ' + os_name + \
    ' --os-code-name ' + os_code_name + \
    ' --arch ' + arch + \
    ' --vcs-info "%s"' % vcs_info + \
    ' --distribution-repository-urls ' + ' '.join(distribution_repository_urls) + \
    ' --distribution-repository-key-files ' + ' ' .join(['/tmp/keys/%d.key' % i for i in range(len(distribution_repository_keys))]) + \
    (' --force' if force else '') + \
    ' --output-dir /tmp/generated_documentation' + \
    ' --dockerfile-dir /tmp/docker_doc',
]
}@
CMD ["@(' && '.join([c.replace('"', '\\"') for c in cmds]))"]


Update xunit to 2.3.8

Update xunit to 2.3.8

@{
# for backward compatibility only
if 'types' not in vars() and 'pattern' in vars():
    types = [('GoogleTestType', pattern)]
}@
    <xunit plugin="xunit@@2.3.8">
      <types>
@[for type_tag_and_pattern in types]@
@{
# expanding these within the for statement leads to a TypeError in empy version 3.3.4 and older
type_tag, pattern = type_tag_and_pattern
assert type_tag in ('GoogleTestType', 'JUnitType'), 'Unsupported test type tag: ' + type_tag
}@
        <@(type_tag)>
          <pattern>@ESCAPE(pattern)</pattern>
          <skipNoTestFiles>true</skipNoTestFiles>
          <failIfNotNew>true</failIfNotNew>
          <deleteOutputFiles>true</deleteOutputFiles>
          <stopProcessingIfError>true</stopProcessingIfError>
        </@(type_tag)>
@[end for]@
      </types>
      <thresholds>
        <org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
          <unstableThreshold>0</unstableThreshold>
          <unstableNewThreshold/>
          <failureThreshold/>
          <failureNewThreshold/>
        </org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
        <org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
          <unstableThreshold/>
          <unstableNewThreshold/>
          <failureThreshold/>
          <failureNewThreshold/>
        </org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
      </thresholds>
      <thresholdMode>1</thresholdMode>
      <extraConfiguration>
        <testTimeMargin>3000</testTimeMargin>
      </extraConfiguration>
    </xunit>

@{
# for backward compatibility only
if 'types' not in vars() and 'pattern' in vars():
    types = [('GoogleTestType', pattern)]
}@
    <xunit plugin="xunit@@2.3.1">
      <types>
@[for type_tag_and_pattern in types]@
@{
# expanding these within the for statement leads to a TypeError in empy version 3.3.4 and older
type_tag, pattern = type_tag_and_pattern
assert type_tag in ('GoogleTestType', 'JUnitType'), 'Unsupported test type tag: ' + type_tag
}@
        <@(type_tag)>
          <pattern>@ESCAPE(pattern)</pattern>
          <skipNoTestFiles>true</skipNoTestFiles>
          <failIfNotNew>true</failIfNotNew>
          <deleteOutputFiles>true</deleteOutputFiles>
          <stopProcessingIfError>true</stopProcessingIfError>
        </@(type_tag)>
@[end for]@
      </types>
      <thresholds>
        <org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
          <unstableThreshold>0</unstableThreshold>
          <unstableNewThreshold/>
          <failureThreshold/>
          <failureNewThreshold/>
        </org.jenkinsci.plugins.xunit.threshold.FailedThreshold>
        <org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
          <unstableThreshold/>
          <unstableNewThreshold/>
          <failureThreshold/>
          <failureNewThreshold/>
        </org.jenkinsci.plugins.xunit.threshold.SkippedThreshold>
      </thresholds>
      <thresholdMode>1</thresholdMode>
      <extraConfiguration>
        <testTimeMargin>3000</testTimeMargin>
      </extraConfiguration>
    </xunit>


add missing key to skip: libopensplice69

%YAML 1.1
# ROS2 Dockerfile database
---
images:
    source:
        base_image: @(os_name):@(os_code_name)
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/source/create_ros_image.Dockerfile.em
        entrypoint_name: docker_images_ros2/source/ros_entrypoint.sh
        template_packages:
            - docker_templates
        upstream_packages:
            - bash-completion
            - git
            - libasio-dev
            - libtinyxml2-dev
            - wget
        ros2_repo_packages:
            - python3-catkin-pkg-modules
            - python3-rosdep
            - python3-vcstool
        pip3_install:
            - argcomplete
            - flake8
            - flake8-blind-except
            - flake8-builtins
            - flake8-class-newline
            - flake8-comprehensions
            - flake8-deprecated
            - flake8-docstrings
            - flake8-import-order
            - flake8-quotes
            - pytest-repeat
            - pytest-rerunfailures
        ws: /root/ros2_ws
        colcon_args:
            - build
            - --cmake-args
                -DSECURITY=ON --no-warn-unused-cli
            - --symlink-install
        rosdep:
            rosdistro_index_url: https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml
            install:
                - --from-paths src
                - --ignore-src
                - --rosdistro bouncy
                - --skip-keys "console_bridge fastcdr fastrtps libopensplice67 libopensplice69 rti-connext-dds-5.3.1 urdfdom_headers"
        vcs:
            ros2:
                repos: https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos

%YAML 1.1
# ROS2 Dockerfile database
---
images:
    source:
        base_image: @(os_name):@(os_code_name)
        maintainer_name: @(maintainer_name)
        template_name: docker_images_ros2/source/create_ros_image.Dockerfile.em
        entrypoint_name: docker_images_ros2/source/ros_entrypoint.sh
        template_packages:
            - docker_templates
        upstream_packages:
            - bash-completion
            - git
            - libasio-dev
            - libtinyxml2-dev
            - wget
        ros2_repo_packages:
            - python3-catkin-pkg-modules
            - python3-rosdep
            - python3-vcstool
        pip3_install:
            - argcomplete
            - flake8
            - flake8-blind-except
            - flake8-builtins
            - flake8-class-newline
            - flake8-comprehensions
            - flake8-deprecated
            - flake8-docstrings
            - flake8-import-order
            - flake8-quotes
            - pytest-repeat
            - pytest-rerunfailures
        ws: /root/ros2_ws
        colcon_args:
            - build
            - --cmake-args
                -DSECURITY=ON --no-warn-unused-cli
            - --symlink-install
        rosdep:
            rosdistro_index_url: https://raw.githubusercontent.com/ros2/rosdistro/ros2/index.yaml
            install:
                - --from-paths src
                - --ignore-src
                - --rosdistro bouncy
                - --skip-keys "console_bridge fastcdr fastrtps libopensplice67 rti-connext-dds-5.3.1 urdfdom_headers"
        vcs:
            ros2:
                repos: https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos


Add notes about why we're doing pointer fixups as soon as possible when restoring presences and visibles.

if (typeof(std.persist) === 'undefined')
    throw new Error('Error.  Do not import this file directly.  Only import it from persistService.em');

(function()
 {

     /**
      Each element of this array contains the unique id given to the
      presence object when it was being persisted.  And each element
      correpsonds to a presence that is trying to be restored in the
      world.
      */
     var allPresStillRest = {};

     var mRestoring = false;

     function registerPresenceStillRestoring(keyName, presObjID)
     {
         if (allPresStillRest[keyName] === undefined)
             allPresStillRest[keyName] = {};
         allPresStillRest[keyName][presObjID] = presObjID;
     }

     /**
      Each restored presence has an onConnected callback.  The
      onConnected callback should be generated from this afterRestored
      function.  All that the callback does is update the nameService
      that we're using with the new presence object and removes this
      presence from the list of presences that we are restoring that
      are still waiting to be connected (in allPresStillRest).

      Second stage of restoration (fixing up pointers to other
      objects) waits until all presences have been connected (polls
      allPresStillRest to see if have zero length).

      @param {int} presObjID, unique name that was given to presence
      before restore.  (ie name that goes into nameService.)

      @param nameService nameService used during restoration.
      */
     function afterRestored(keyName,presObjID,nameService,cb)
     {
         var returner = function()
         {
             //insert the presence into nameService;
             nameService.insertObjectWithName(system.self,presObjID);
             delete allPresStillRest[keyName][presObjID];
             if (Object.keys(allPresStillRest[keyName]).length == 0) {
                 delete allPresStillRest[keyName];
                 cb(true, null); // Not sure about this being null....
             }
        };
         return returner;
     }

     function checkIsTriplet(toCheck)
     {
         if ((typeof(toCheck) !== 'object') || (!('length' in toCheck)) || (toCheck.length != 3))
             return false;

         return true;
     }

     function tripletGetIndexName(triplet)
     {
         if (!checkIsTriplet(triplet))
         {
             throw new Error('Error in tripletGetIndexName.  Requires triplet to be passed in');
         }

         return triplet[0];
     }

     function tripletGetValue(triplet)
     {
         if (!checkIsTriplet(triplet))
             throw new Error('Error in tripletGetValue.  Requires triplet to be passed in');

         var type = tripletGetType(triplet);
         if (type == 'number')
             return parseFloat(triplet[1]);
         if (type == 'string')
             return triplet[1];
         if (type == 'boolean')
             return (triplet[1] == 'true');

         return triplet[1];
     }

     function tripletGetType(triplet)
     {
         if (!checkIsTriplet(triplet))
             throw new Error('Error in tripletGetType.  Requires triplet to be passed in');
         return triplet[2];
     }

    /**
     @param {array} triplet Array containing three values.  Indices of
     array follow:
       0 : index
       1 : value to set to/object pointer/'null'
       2 : type record

     @return {boolean} Returns true if the value in this object is a
     value type
     */
    function tripletIsValueType (triplet)
    {
        if (! checkIsTriplet(triplet))
            throw new Error('Error in checkTripletIsValueType.  Requires triplet to be passed in');

        var tripType = tripletGetType(triplet);

        if ((tripType != 'object') && (tripType != 'function') &&
            (tripType!=std.persist.SYSTEM_TYPE_STRING) &&
            (tripType!=std.persist.PRESENCE_OBJECT_TYPE_STRING) &&
            (tripType!=std.persist.VISIBLE_TYPE_STRING) &&
            (tripType!=std.persist.TIMER_TYPE_STRING) &&
            (tripType!=std.persist.PRESENCE_ENTRY_TYPE_STRING) &&
            (tripType!=std.persist.FUNCTION_OBJECT_TYPE_STRING) &&
            (tripType!=std.persist.BASIC_OBJECT_TYPE_STRING))
            return true;

        return false;
    };

     /**
      @param {int} ptrId The unique name of the object that should be
      referenced by calling localCopyToPoint[index]
      @param index of the local object to perform fixup on.
      @param {object} localCopyToPoint localCopyToPoint[index] should be the new
      object pointer
      @param {array} allToFix an array.  Push the above three arguments onto that
      array (as an array).

      After rest of deserialization occurs, final step is to call
      performFinalFixups with this array as an argument.
      performPtrFinalFixups traverses array, and points
      localCopyToPoint[index] to the objects described by objPtrToFix.
      */
     function registerFixupObjectPointer(ptrId, index, localCopyToPoint, allToFix)
     {
         allToFix.push([ptrId, index,localCopyToPoint]);
     };

     /**
      locaCopyToPoint[index] should end up pointing to the object represented
      by the lookup into nameService of ptrId

      @see registerFixupObjectPointer
      @see fixSinglePtr
      */
     function fixSinglePtr (ptrId, index,localCopyToPoint,nameService)
     {
         if ((typeof(localCopyToPoint) != 'object') || (localCopyToPoint== null))
             throw new Error('Error in fixSinglePtr.  Should not have received non-obect or null ptr record.');

         var fixedObj = nameService.lookupObject(ptrId);
         if (fixedObj == nameService.DNE)
             throw new Error('Error in fixSinglePtr.  Have no record of object that you are trying to point to: ' + fixedObj);

         localCopyToPoint[index] = fixedObj;
     };

     /**
      @param {array} allToFix array.  Each element has three values. [0]
      ptrId, [1] index, [2] localCopyToPoint.

      Runs through array generated by calls to registerFixupObjectPointer,
      and individually performs fixups for each one.

      @see registerFixupObjectPointer
      @see fixSinglePtr
      */
     function performPtrFinalFixups(allToFix,nameService)
     {
         for (var s in allToFix)
             fixSinglePtr(allToFix[s][0],allToFix[s][1],allToFix[s][2],nameService);
     };

     /**
      fixReferences opens the keyName table, and returns an object whose
      subgraph is rooted at the object with id ptrId. Note: all objects the
      root object references may not be linked to correctly.  Need to call
      performPtrFinalFixups on ptrsToFix after running this function.

      @param {keyName}, Passed to the backend.  This is the entry to
      access.

      @param {int}, ptrId, Each object has a unique id.  ptrId is the
      identifier for the object that we should be fixing references for (in
      the keyName table).

      @param {array} ptrsToFix is an array that tracks all objects that we
      will need to fixup the references too.  See performFixupPtr function.

      @param nameService can be used to lookup the ids for objects that
      we've already re-read.

      @param cb callback to invoke when complete. Passed success flag (boolean)
      and, if successful, an object whose subgraph is rooted at the object with id ptrId.

      */
     function fixReferences(keyName, ptrId, ptrsToFix, nameService, cb)
     {
         // Before starting the read, insert the object as a
         // known-but-not-yet-available object in the name
         // service. This should prevent others from starting another
         // read on it but won't make it available yet.
         nameService.insertNA(ptrId);
         readObject(
             keyName,ptrId,
             std.core.bind(finishFixReferences, undefined, keyName, ptrId, ptrsToFix, nameService, cb) // + success, object
         );
     }

     function finishFixReferences(keyName, ptrId, ptrsToFix, nameService, cb, success, unfixedObj) {
         if (!success)
         {
             cb(false);
             return;
         }

         var id = unfixedObj['mID'];
         if (id != ptrId) //throw new Error('Error: ptrId and object id must be identical');
             cb(false);

         if (nameService.lookupObject(ptrId) != nameService.NA) {
             throw new Error("Error. Called fixReferences on unknown object or object I've already seen: " + keyName);
         }

         var type = unfixedObj['type'];
         if (type == std.persist.FUNCTION_OBJECT_TYPE_STRING)
             restoreFunction(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.PRESENCE_OBJECT_TYPE_STRING)
             restorePresence(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.BASIC_OBJECT_TYPE_STRING)
             restoreBasicObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.VEC_TYPE_STRING)
             restoreVec3Object(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.QUAT_TYPE_STRING)
             restoreQuatObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.VISIBLE_TYPE_STRING)
             restoreVisibleObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else
             throw new Error('Error in fixReferences.  Do not have any other types in the system to restore from.');
     }

     /**
      @see fixReferences for arguments
      Returns a new visible object.
      */
     function restoreVisibleObject(keyName, visRecord,ptrId,ptrsToFix,nameService,cb)
     {
         var pToFix = [];
         restoreBasicObject(
             keyName,visRecord,ptrId,pToFix,nameService,
             std.core.bind(finishRestoreVisibleObject, undefined, keyname, visRecord, ptrId, pToFix, nameService, cb)
         );
     };
     function finishRestoreVisibleObject(keyName, visRecord,ptrId,pToFix,nameService,cb, success, toRestoreFrom) {
         if(!success) {
             cb(false);
             return;
         }

         // Note that we use a separate set of ptrs and do a fixup
         // here because multiple fields in a presence might point to
         // the same object (e.g. identical strings). In that case, we
         // need to fix up pointers before we can use the object
         // safely. Note that this currently only works because we
         // don't serialize any extra fields on presences. When we do,
         // we can't do ptr fixups until the entire object graph is
         // restored.
         //
         //perform the fixups for the objects that this presence was
         //trying to point to.  (Eg. pos object, vel obj, etc.)
         performPtrFinalFixups(pToFix,nameService);

         var returner = system.createVisible(
             toRestoreFrom.sporef,
             toRestoreFrom.pos,
             toRestoreFrom.vel,
             toRestoreFrom.posTime,
             toRestoreFrom.orient,
             toRestoreFrom.orientVel,
             toRestoreFrom.orientTime,
             toRestoreFrom.pos,
             toRestoreFrom.scale,
             toRestoreFrom.mesh,
             toRestoreFrom.physics,
             toRestoreFrom.solidAngleQuery
         );

         cb(true, returner);
     }

     /**
      @see fixReferencs for arguments.
      Returns a new vec3.
      */
     function restoreVec3Object(keyName, unfixedObj,ptrId,ptrsToFix,nameService, cb)
     {
         //lkjs: may want some check here.
         var x = getValueField(unfixedObj,'x');
         var y = getValueField(unfixedObj,'y');
         var z = getValueField(unfixedObj,'z');
         var returner = new util.Vec3(x,y,z);
         nameService.insertObjectWithName(returner,ptrId);
         cb(true, returner);
     }

     /**
      @see fixReferencs for arguments.
      Returns a new quaternion.
      */
     function restoreQuatObject(keyName, unfixedObj,ptrId,ptrsToFix,nameService, cb)
     {
         var x = getValueField(unfixedObj,'x');
         var y = getValueField(unfixedObj,'y');
         var z = getValueField(unfixedObj,'z');
         var w = getValueField(unfixedObj,'w');

         var returner = new util.Quaternion(x,y,z,w);
         nameService.insertObjectWithName(returner,ptrId);
         cb(true, returner);
     }

     /**
      @param unfixedObj Is an object that is read in directly from the
      backend.  It has three types of fields: 1) triplets, 2) mID (obj
      id), 3) type (obj type).

      @param Field name that we're looking for in one of the triplets.

      @return returns the value of the triplet associated with
      filedName

      @throw Throws an error if fieldName does not exist as a field in
      any of unfixedObj's triplets.

      This function runs through all the triplets in unfixedObj, and
      returns the value of the triplet that matches the field.
      */
     function getValueField(unfixedObj,fieldName)
     {
         for (var s in unfixedObj)
         {
             if ((s == 'mID') || (s == 'type'))
                 continue;

             var propValTypeTriple = unfixedObj[s];

             var tripFieldName = tripletGetIndexName(unfixedObj[s]);
             if (tripFieldName == fieldName)
                 return tripletGetValue(propValTypeTriple);
         }
         throw new Error('Error in getValueField.  Have no field named: '+ fieldName);
     }

     /**
      For keyName,ptrId,ptrsToFix, and nameService, @see fixReferences.

      unfixedPres has all the data that you would get from a call to
      getAllData on a presence.

      */
     function restorePresence(keyName,unfixedPres,ptrId,ptrsToFix,nameService, cb)
     {
         var pToFix = [];
         restoreBasicObject(
             keyName,unfixedPres,ptrId,pToFix,nameService,
             std.core.bind(finishRestorePresence, undefined, keyName, unfixedPres, ptrId, pToFix, nameService, cb) // + success, obj
         );
     }
     function finishRestorePresence(keyName,unfixedPres,ptrId,pToFix,nameService, cb, success, toRestoreFrom) {
         if(!success) {
             cb(false);
             return;
         }

         // Note that we use a separate set of ptrs and do a fixup
         // here because multiple fields in a presence might point to
         // the same object (e.g. identical strings). In that case, we
         // need to fix up pointers before we can use the object
         // safely. Note that this currently only works because we
         // don't serialize any extra fields on presences. When we do,
         // we can't do ptr fixups until the entire object graph is
         // restored.
         //
         //perform the fixups for the objects that this presence was
         //trying to point to.  (Eg. pos object, vel obj, etc.)
         performPtrFinalFixups(pToFix,nameService);

         for (var s in system.presences)
         {
             if (system.presences[s].toString() == toRestoreFrom.sporef)
             {
                 cb(true,system.presences[s]);
                 return;
             }
         }

         //tells the system that we have begun trying to restore this
         //presence, and not to continue with later stages of
         //restoration (fixing looped object pointers) until the
         //system has connected this presence.
         registerPresenceStillRestoring(keyName, ptrId);

         var onConnectCB = afterRestored(keyName,ptrId,nameService,cb);
         system.restorePresence(
             toRestoreFrom.sporef,
             toRestoreFrom.pos,
             toRestoreFrom.vel,
             toRestoreFrom.posTime,
             toRestoreFrom.orient,
             toRestoreFrom.orientVel,
             toRestoreFrom.orientTime,
             toRestoreFrom.mesh,
             toRestoreFrom.physics,
             toRestoreFrom.scale,
             toRestoreFrom.isCleared,
             toRestoreFrom.contextId,
             toRestoreFrom.isConnected,
             onConnectCB,
             toRestoreFrom.isSuspended,
             toRestoreFrom.suspendedVelocity,
             toRestoreFrom.suspendedOrientationVelocity,
             toRestoreFrom.solidAngleQuery
         );
     };

     /**
      For keyName,ptrId,ptrsToFix, and nameService, @see fixReferences.

      unfixedFunc right now just has one field: 'funcField' with the
      text of the function that we're creating.
      */
     function restoreFunction(keyName,unfixedFunc,ptrId,ptrsToFix,nameService, cb)
     {
         //FIXME: lkjs;  GROSS!
         var funcTriple = unfixedFunc[0];

         var index = tripletGetIndexName(funcTriple);
         if (index != 'funcField')
             throw new Error('Error restoring function.  Restoring object does not have funcField.');

         var funcAsString = tripletGetValue(funcTriple);
         funcAsString = '(' + funcAsString + ')';

         var returner = null;
         var success = true;
         try
         {
             returner = system.eval(funcAsString);
         }
         catch (excep)
         {
             system.print('ERROR: Error in restoreFunction.  Trying to restore a function with faulty syntax. Key: ' + keyName + '\n');
             returner = function(){};
             success = false;
         }
         nameService.insertObjectWithName(returner,ptrId);
         cb(success, returner);
     }

     /**
      For keyName, ptrId,ptrsToFix, and nameService, @see fixReferences.

      @param unfixedObj is the object that we get back from reading
      from reading from backend.  It is a basic object (not a
      function, presence, system obj, etc.).  This function runs
      through all of its fields and registers them to be fixed up.

      */
     function restoreBasicObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb)
     {
         var returner = { };
         nameService.insertObjectWithName(returner,ptrId);
         //run through all the fields in unfixedObj.  If the field is a
         //value type, point returner to the new field right away.  If the
         //field is an object type and we have a copy of that object, then
         //point returner to that new object right away.  If the field is
         //an object type and we do not have a copy of that object, then
         //register returner to be fixed-up with the new pointer later.

         var unfinished_fields = 0;
         var did_callback = false;
         var finish_field_cb = function(success, val) {
             if (!success && !did_callback) {
                 did_callback = true;
                 cb(false);
                 return;
             }
             unfinished_fields -= 1;
             if (unfinished_fields == 0) {
                 did_callback = true;
                 cb(true, returner);
             }
         };
         for (var s in unfixedObj)
         {
             if ((s == 'mID') || (s == 'type'))
                 continue;

             var index = tripletGetIndexName(unfixedObj[s]);

             //sets to value type
             if (tripletIsValueType(unfixedObj[s]))
                 returner[index] = tripletGetValue(unfixedObj[s]);
             else
             {
                 if ((tripletGetType(unfixedObj[s])) == 'null')
                     returner[index] = null;
                 else
                 {
                     var ptrIdInner  = tripletGetValue(unfixedObj[s]);
                     var ptrObj = nameService.lookupObject(ptrIdInner);
                     if (ptrObj == nameService.DNE)
                     {
                         //will have to register this pointer to be fixed up
                         registerFixupObjectPointer( ptrIdInner ,index,returner,ptrsToFix);

                         // We need to request the data from storage since we didn't even know about it yet
                         unfinished_fields += 1;
                         fixReferences(keyName,ptrIdInner,ptrsToFix,nameService, std.core.bind(finish_field_cb, undefined));
                     }
                     else if (ptrObj == nameService.NA) {
                         //will have to register this pointer to be fixed up, but the request for data is already out
                         registerFixupObjectPointer( ptrIdInner ,index,returner,ptrsToFix);
                     }
                     else
                     {
                         //already have the object.  just link to it.
                         returner[index] = ptrObj;
                     }
                 }
             }
         }

         // Special case for empty objects
         if (unfinished_fields == 0) {
             cb(true, returner);
         }
     };

     /**
      Returns true if we're in the middle of a restore operation.
      Otherwise, returns false.
      */
     std.persist.inRestore = function()
     {
         return mRestoring;
     };

     /**
      @see std.persist.restoreFromAndGetNamesAsync
      */
     std.persist.restoreFromAsync = function (keyName,cb)
     {
         return std.persist.restoreFromAndGetNamesAsync(keyName,0,cb);
     };

     /**
      This function should be used if the object graph that you are
      trying to restore has presences in it, and you need to wait for
      the system to actually connect these presences.

      @param cb Takes in three parameters, first is restored obj graph
      (if pres failure, all presences become null objs.), second
      boolean for success (ie true if eveything restored
      appropriately, and space allowed new presences to reconnect,
      false otherwise), the third is the nameService that we used.
      */
     std.persist.restoreFromAndGetNamesAsync = function (keyName,id,cb)
     {
         if (std.persist.inRestore())
             throw new Error('Error, cannot request additional restores when in middle of current restore.  Check back later.');
         mRestoring = true;

         var nameService = new std.persist.NameService();
         var ptrsToFix = [];

         // Setup a timeout in case we fail to get all presences reconnected
         var restoreCheckback = function() {
             cb(false);
         };
         var tout = system.timeout(60,restoreCheckback);

         fixReferences(
             keyName, id,ptrsToFix,nameService,
             std.core.bind(finishRestoreFromAndGetNamesAsync, undefined, keyName, id, cb, ptrsToFix, nameService, tout) // + success, obj
         );
     };

     var finishRestoreFromAndGetNamesAsync = function (keyName,id,cb, ptrsToFix, nameService, timeout, success, returner) {
         // Clear timeout since we've either succeeded or permanently failed
         if (!timeout.cleared) {
             timeout.clear();
             timeout.cleared = true;
         }

         if (!success) {
             mRestoring = false;
             cb(false);
             return;
         }
         if (allPresStillRest[keyName] !== undefined && Object.keys(allPresStillRest[keyName]).length != 0) {
             system.print("Error: Shouldn't get finishRestoreFromAndGetNamesAsync callback until all presences are restored.\n");
             mRestoring = false;
             cb(false);
             return;
         }

         // Success
         performPtrFinalFixups(ptrsToFix,nameService);
         mRestoring = false;
         cb(true,returner,nameService);
     };

 })();

if (typeof(std.persist) === 'undefined')
    throw new Error('Error.  Do not import this file directly.  Only import it from persistService.em');

(function()
 {

     /**
      Each element of this array contains the unique id given to the
      presence object when it was being persisted.  And each element
      correpsonds to a presence that is trying to be restored in the
      world.
      */
     var allPresStillRest = {};

     var mRestoring = false;

     function registerPresenceStillRestoring(keyName, presObjID)
     {
         if (allPresStillRest[keyName] === undefined)
             allPresStillRest[keyName] = {};
         allPresStillRest[keyName][presObjID] = presObjID;
     }

     /**
      Each restored presence has an onConnected callback.  The
      onConnected callback should be generated from this afterRestored
      function.  All that the callback does is update the nameService
      that we're using with the new presence object and removes this
      presence from the list of presences that we are restoring that
      are still waiting to be connected (in allPresStillRest).

      Second stage of restoration (fixing up pointers to other
      objects) waits until all presences have been connected (polls
      allPresStillRest to see if have zero length).

      @param {int} presObjID, unique name that was given to presence
      before restore.  (ie name that goes into nameService.)

      @param nameService nameService used during restoration.
      */
     function afterRestored(keyName,presObjID,nameService,cb)
     {
         var returner = function()
         {
             //insert the presence into nameService;
             nameService.insertObjectWithName(system.self,presObjID);
             delete allPresStillRest[keyName][presObjID];
             if (Object.keys(allPresStillRest[keyName]).length == 0) {
                 delete allPresStillRest[keyName];
                 cb(true, null); // Not sure about this being null....
             }
        };
         return returner;
     }

     function checkIsTriplet(toCheck)
     {
         if ((typeof(toCheck) !== 'object') || (!('length' in toCheck)) || (toCheck.length != 3))
             return false;

         return true;
     }

     function tripletGetIndexName(triplet)
     {
         if (!checkIsTriplet(triplet))
         {
             throw new Error('Error in tripletGetIndexName.  Requires triplet to be passed in');
         }

         return triplet[0];
     }

     function tripletGetValue(triplet)
     {
         if (!checkIsTriplet(triplet))
             throw new Error('Error in tripletGetValue.  Requires triplet to be passed in');

         var type = tripletGetType(triplet);
         if (type == 'number')
             return parseFloat(triplet[1]);
         if (type == 'string')
             return triplet[1];
         if (type == 'boolean')
             return (triplet[1] == 'true');

         return triplet[1];
     }

     function tripletGetType(triplet)
     {
         if (!checkIsTriplet(triplet))
             throw new Error('Error in tripletGetType.  Requires triplet to be passed in');
         return triplet[2];
     }

    /**
     @param {array} triplet Array containing three values.  Indices of
     array follow:
       0 : index
       1 : value to set to/object pointer/'null'
       2 : type record

     @return {boolean} Returns true if the value in this object is a
     value type
     */
    function tripletIsValueType (triplet)
    {
        if (! checkIsTriplet(triplet))
            throw new Error('Error in checkTripletIsValueType.  Requires triplet to be passed in');

        var tripType = tripletGetType(triplet);

        if ((tripType != 'object') && (tripType != 'function') &&
            (tripType!=std.persist.SYSTEM_TYPE_STRING) &&
            (tripType!=std.persist.PRESENCE_OBJECT_TYPE_STRING) &&
            (tripType!=std.persist.VISIBLE_TYPE_STRING) &&
            (tripType!=std.persist.TIMER_TYPE_STRING) &&
            (tripType!=std.persist.PRESENCE_ENTRY_TYPE_STRING) &&
            (tripType!=std.persist.FUNCTION_OBJECT_TYPE_STRING) &&
            (tripType!=std.persist.BASIC_OBJECT_TYPE_STRING))
            return true;

        return false;
    };

     /**
      @param {int} ptrId The unique name of the object that should be
      referenced by calling localCopyToPoint[index]
      @param index of the local object to perform fixup on.
      @param {object} localCopyToPoint localCopyToPoint[index] should be the new
      object pointer
      @param {array} allToFix an array.  Push the above three arguments onto that
      array (as an array).

      After rest of deserialization occurs, final step is to call
      performFinalFixups with this array as an argument.
      performPtrFinalFixups traverses array, and points
      localCopyToPoint[index] to the objects described by objPtrToFix.
      */
     function registerFixupObjectPointer(ptrId, index, localCopyToPoint, allToFix)
     {
         allToFix.push([ptrId, index,localCopyToPoint]);
     };

     /**
      locaCopyToPoint[index] should end up pointing to the object represented
      by the lookup into nameService of ptrId

      @see registerFixupObjectPointer
      @see fixSinglePtr
      */
     function fixSinglePtr (ptrId, index,localCopyToPoint,nameService)
     {
         if ((typeof(localCopyToPoint) != 'object') || (localCopyToPoint== null))
             throw new Error('Error in fixSinglePtr.  Should not have received non-obect or null ptr record.');

         var fixedObj = nameService.lookupObject(ptrId);
         if (fixedObj == nameService.DNE)
             throw new Error('Error in fixSinglePtr.  Have no record of object that you are trying to point to: ' + fixedObj);

         localCopyToPoint[index] = fixedObj;
     };

     /**
      @param {array} allToFix array.  Each element has three values. [0]
      ptrId, [1] index, [2] localCopyToPoint.

      Runs through array generated by calls to registerFixupObjectPointer,
      and individually performs fixups for each one.

      @see registerFixupObjectPointer
      @see fixSinglePtr
      */
     function performPtrFinalFixups(allToFix,nameService)
     {
         for (var s in allToFix)
             fixSinglePtr(allToFix[s][0],allToFix[s][1],allToFix[s][2],nameService);
     };

     /**
      fixReferences opens the keyName table, and returns an object whose
      subgraph is rooted at the object with id ptrId. Note: all objects the
      root object references may not be linked to correctly.  Need to call
      performPtrFinalFixups on ptrsToFix after running this function.

      @param {keyName}, Passed to the backend.  This is the entry to
      access.

      @param {int}, ptrId, Each object has a unique id.  ptrId is the
      identifier for the object that we should be fixing references for (in
      the keyName table).

      @param {array} ptrsToFix is an array that tracks all objects that we
      will need to fixup the references too.  See performFixupPtr function.

      @param nameService can be used to lookup the ids for objects that
      we've already re-read.

      @param cb callback to invoke when complete. Passed success flag (boolean)
      and, if successful, an object whose subgraph is rooted at the object with id ptrId.

      */
     function fixReferences(keyName, ptrId, ptrsToFix, nameService, cb)
     {
         // Before starting the read, insert the object as a
         // known-but-not-yet-available object in the name
         // service. This should prevent others from starting another
         // read on it but won't make it available yet.
         nameService.insertNA(ptrId);
         readObject(
             keyName,ptrId,
             std.core.bind(finishFixReferences, undefined, keyName, ptrId, ptrsToFix, nameService, cb) // + success, object
         );
     }

     function finishFixReferences(keyName, ptrId, ptrsToFix, nameService, cb, success, unfixedObj) {
         if (!success)
         {
             cb(false);
             return;
         }

         var id = unfixedObj['mID'];
         if (id != ptrId) //throw new Error('Error: ptrId and object id must be identical');
             cb(false);

         if (nameService.lookupObject(ptrId) != nameService.NA) {
             throw new Error("Error. Called fixReferences on unknown object or object I've already seen: " + keyName);
         }

         var type = unfixedObj['type'];
         if (type == std.persist.FUNCTION_OBJECT_TYPE_STRING)
             restoreFunction(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.PRESENCE_OBJECT_TYPE_STRING)
             restorePresence(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.BASIC_OBJECT_TYPE_STRING)
             restoreBasicObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.VEC_TYPE_STRING)
             restoreVec3Object(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.QUAT_TYPE_STRING)
             restoreQuatObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else if (type == std.persist.VISIBLE_TYPE_STRING)
             restoreVisibleObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb);
         else
             throw new Error('Error in fixReferences.  Do not have any other types in the system to restore from.');
     }

     /**
      @see fixReferences for arguments
      Returns a new visible object.
      */
     function restoreVisibleObject(keyName, visRecord,ptrId,ptrsToFix,nameService,cb)
     {
         var pToFix = [];
         restoreBasicObject(
             keyName,visRecord,ptrId,pToFix,nameService,
             std.core.bind(finishRestoreVisibleObject, undefined, keyname, visRecord, ptrId, pToFix, nameService, cb)
         );
     };
     function finishRestoreVisibleObject(keyName, visRecord,ptrId,pToFix,nameService,cb, success, toRestoreFrom) {
         if(!success) {
             cb(false);
             return;
         }

         //perform the fixups for the objects that this presence was
         //trying to point to.  (Eg. pos object, vel obj, etc.)
         performPtrFinalFixups(pToFix,nameService);

         var returner = system.createVisible(
             toRestoreFrom.sporef,
             toRestoreFrom.pos,
             toRestoreFrom.vel,
             toRestoreFrom.posTime,
             toRestoreFrom.orient,
             toRestoreFrom.orientVel,
             toRestoreFrom.orientTime,
             toRestoreFrom.pos,
             toRestoreFrom.scale,
             toRestoreFrom.mesh,
             toRestoreFrom.physics,
             toRestoreFrom.solidAngleQuery
         );

         cb(true, returner);
     }

     /**
      @see fixReferencs for arguments.
      Returns a new vec3.
      */
     function restoreVec3Object(keyName, unfixedObj,ptrId,ptrsToFix,nameService, cb)
     {
         //lkjs: may want some check here.
         var x = getValueField(unfixedObj,'x');
         var y = getValueField(unfixedObj,'y');
         var z = getValueField(unfixedObj,'z');
         var returner = new util.Vec3(x,y,z);
         nameService.insertObjectWithName(returner,ptrId);
         cb(true, returner);
     }

     /**
      @see fixReferencs for arguments.
      Returns a new quaternion.
      */
     function restoreQuatObject(keyName, unfixedObj,ptrId,ptrsToFix,nameService, cb)
     {
         var x = getValueField(unfixedObj,'x');
         var y = getValueField(unfixedObj,'y');
         var z = getValueField(unfixedObj,'z');
         var w = getValueField(unfixedObj,'w');

         var returner = new util.Quaternion(x,y,z,w);
         nameService.insertObjectWithName(returner,ptrId);
         cb(true, returner);
     }

     /**
      @param unfixedObj Is an object that is read in directly from the
      backend.  It has three types of fields: 1) triplets, 2) mID (obj
      id), 3) type (obj type).

      @param Field name that we're looking for in one of the triplets.

      @return returns the value of the triplet associated with
      filedName

      @throw Throws an error if fieldName does not exist as a field in
      any of unfixedObj's triplets.

      This function runs through all the triplets in unfixedObj, and
      returns the value of the triplet that matches the field.
      */
     function getValueField(unfixedObj,fieldName)
     {
         for (var s in unfixedObj)
         {
             if ((s == 'mID') || (s == 'type'))
                 continue;

             var propValTypeTriple = unfixedObj[s];

             var tripFieldName = tripletGetIndexName(unfixedObj[s]);
             if (tripFieldName == fieldName)
                 return tripletGetValue(propValTypeTriple);
         }
         throw new Error('Error in getValueField.  Have no field named: '+ fieldName);
     }

     /**
      For keyName,ptrId,ptrsToFix, and nameService, @see fixReferences.

      unfixedPres has all the data that you would get from a call to
      getAllData on a presence.

      */
     function restorePresence(keyName,unfixedPres,ptrId,ptrsToFix,nameService, cb)
     {
         var pToFix = [];
         restoreBasicObject(
             keyName,unfixedPres,ptrId,pToFix,nameService,
             std.core.bind(finishRestorePresence, undefined, keyName, unfixedPres, ptrId, pToFix, nameService, cb) // + success, obj
         );
     }
     function finishRestorePresence(keyName,unfixedPres,ptrId,pToFix,nameService, cb, success, toRestoreFrom) {
         if(!success) {
             cb(false);
             return;
         }

         //perform the fixups for the objects that this presence was
         //trying to point to.  (Eg. pos object, vel obj, etc.)
         performPtrFinalFixups(pToFix,nameService);

         for (var s in system.presences)
         {
             if (system.presences[s].toString() == toRestoreFrom.sporef)
             {
                 cb(true,system.presences[s]);
                 return;
             }
         }

         //tells the system that we have begun trying to restore this
         //presence, and not to continue with later stages of
         //restoration (fixing looped object pointers) until the
         //system has connected this presence.
         registerPresenceStillRestoring(keyName, ptrId);

         var onConnectCB = afterRestored(keyName,ptrId,nameService,cb);
         system.restorePresence(
             toRestoreFrom.sporef,
             toRestoreFrom.pos,
             toRestoreFrom.vel,
             toRestoreFrom.posTime,
             toRestoreFrom.orient,
             toRestoreFrom.orientVel,
             toRestoreFrom.orientTime,
             toRestoreFrom.mesh,
             toRestoreFrom.physics,
             toRestoreFrom.scale,
             toRestoreFrom.isCleared,
             toRestoreFrom.contextId,
             toRestoreFrom.isConnected,
             onConnectCB,
             toRestoreFrom.isSuspended,
             toRestoreFrom.suspendedVelocity,
             toRestoreFrom.suspendedOrientationVelocity,
             toRestoreFrom.solidAngleQuery
         );
     };

     /**
      For keyName,ptrId,ptrsToFix, and nameService, @see fixReferences.

      unfixedFunc right now just has one field: 'funcField' with the
      text of the function that we're creating.
      */
     function restoreFunction(keyName,unfixedFunc,ptrId,ptrsToFix,nameService, cb)
     {
         //FIXME: lkjs;  GROSS!
         var funcTriple = unfixedFunc[0];

         var index = tripletGetIndexName(funcTriple);
         if (index != 'funcField')
             throw new Error('Error restoring function.  Restoring object does not have funcField.');

         var funcAsString = tripletGetValue(funcTriple);
         funcAsString = '(' + funcAsString + ')';

         var returner = null;
         var success = true;
         try
         {
             returner = system.eval(funcAsString);
         }
         catch (excep)
         {
             system.print('ERROR: Error in restoreFunction.  Trying to restore a function with faulty syntax. Key: ' + keyName + '\n');
             returner = function(){};
             success = false;
         }
         nameService.insertObjectWithName(returner,ptrId);
         cb(success, returner);
     }

     /**
      For keyName, ptrId,ptrsToFix, and nameService, @see fixReferences.

      @param unfixedObj is the object that we get back from reading
      from reading from backend.  It is a basic object (not a
      function, presence, system obj, etc.).  This function runs
      through all of its fields and registers them to be fixed up.

      */
     function restoreBasicObject(keyName,unfixedObj,ptrId,ptrsToFix,nameService,cb)
     {
         var returner = { };
         nameService.insertObjectWithName(returner,ptrId);
         //run through all the fields in unfixedObj.  If the field is a
         //value type, point returner to the new field right away.  If the
         //field is an object type and we have a copy of that object, then
         //point returner to that new object right away.  If the field is
         //an object type and we do not have a copy of that object, then
         //register returner to be fixed-up with the new pointer later.

         var unfinished_fields = 0;
         var did_callback = false;
         var finish_field_cb = function(success, val) {
             if (!success && !did_callback) {
                 did_callback = true;
                 cb(false);
                 return;
             }
             unfinished_fields -= 1;
             if (unfinished_fields == 0) {
                 did_callback = true;
                 cb(true, returner);
             }
         };
         for (var s in unfixedObj)
         {
             if ((s == 'mID') || (s == 'type'))
                 continue;

             var index = tripletGetIndexName(unfixedObj[s]);

             //sets to value type
             if (tripletIsValueType(unfixedObj[s]))
                 returner[index] = tripletGetValue(unfixedObj[s]);
             else
             {
                 if ((tripletGetType(unfixedObj[s])) == 'null')
                     returner[index] = null;
                 else
                 {
                     var ptrIdInner  = tripletGetValue(unfixedObj[s]);
                     var ptrObj = nameService.lookupObject(ptrIdInner);
                     if (ptrObj == nameService.DNE)
                     {
                         //will have to register this pointer to be fixed up
                         registerFixupObjectPointer( ptrIdInner ,index,returner,ptrsToFix);

                         // We need to request the data from storage since we didn't even know about it yet
                         unfinished_fields += 1;
                         fixReferences(keyName,ptrIdInner,ptrsToFix,nameService, std.core.bind(finish_field_cb, undefined));
                     }
                     else if (ptrObj == nameService.NA) {
                         //will have to register this pointer to be fixed up, but the request for data is already out
                         registerFixupObjectPointer( ptrIdInner ,index,returner,ptrsToFix);
                     }
                     else
                     {
                         //already have the object.  just link to it.
                         returner[index] = ptrObj;
                     }
                 }
             }
         }

         // Special case for empty objects
         if (unfinished_fields == 0) {
             cb(true, returner);
         }
     };

     /**
      Returns true if we're in the middle of a restore operation.
      Otherwise, returns false.
      */
     std.persist.inRestore = function()
     {
         return mRestoring;
     };

     /**
      @see std.persist.restoreFromAndGetNamesAsync
      */
     std.persist.restoreFromAsync = function (keyName,cb)
     {
         return std.persist.restoreFromAndGetNamesAsync(keyName,0,cb);
     };

     /**
      This function should be used if the object graph that you are
      trying to restore has presences in it, and you need to wait for
      the system to actually connect these presences.

      @param cb Takes in three parameters, first is restored obj graph
      (if pres failure, all presences become null objs.), second
      boolean for success (ie true if eveything restored
      appropriately, and space allowed new presences to reconnect,
      false otherwise), the third is the nameService that we used.
      */
     std.persist.restoreFromAndGetNamesAsync = function (keyName,id,cb)
     {
         if (std.persist.inRestore())
             throw new Error('Error, cannot request additional restores when in middle of current restore.  Check back later.');
         mRestoring = true;

         var nameService = new std.persist.NameService();
         var ptrsToFix = [];

         // Setup a timeout in case we fail to get all presences reconnected
         var restoreCheckback = function() {
             cb(false);
         };
         var tout = system.timeout(60,restoreCheckback);

         fixReferences(
             keyName, id,ptrsToFix,nameService,
             std.core.bind(finishRestoreFromAndGetNamesAsync, undefined, keyName, id, cb, ptrsToFix, nameService, tout) // + success, obj
         );
     };

     var finishRestoreFromAndGetNamesAsync = function (keyName,id,cb, ptrsToFix, nameService, timeout, success, returner) {
         // Clear timeout since we've either succeeded or permanently failed
         if (!timeout.cleared) {
             timeout.clear();
             timeout.cleared = true;
         }

         if (!success) {
             mRestoring = false;
             cb(false);
             return;
         }
         if (allPresStillRest[keyName] !== undefined && Object.keys(allPresStillRest[keyName]).length != 0) {
             system.print("Error: Shouldn't get finishRestoreFromAndGetNamesAsync callback until all presences are restored.\n");
             mRestoring = false;
             cb(false);
             return;
         }

         // Success
         performPtrFinalFixups(ptrsToFix,nameService);
         mRestoring = false;
         cb(true,returner,nameService);
     };

 })();


verify only set child if container still exists

Herd.AssetContainerComponent = Ember.Component.extend
  action: 'generateChild'
  classNames: ['asset-container']
  bgImage: true
  asset: null
  child: null
  transform: null
  t: null
  n: null
  suffix: null

  combinedName: ~>
    if @suffix
      [@n,@suffix].join '-'
    else
      @n

  +computed child asset
  isImage: ->
    return @asset?.type == 'Herd::Image' unless @child
    @child.type == 'Herd::Image' and !@bgImage

  +computed child asset
  isVideo: ->
    return @asset?.type == 'Herd::Video' unless @child
    @child.type == 'Herd::Video'

  +computed child.fileName
  assetUrl: ->
    if @child
      if Ember.empty @child.fileName
        return "https://d13yacurqjgara.cloudfront.net/users/82092/screenshots/1073359/spinner.gif"
      else
        return "#{@child?.url}?b=#{@child.updatedAt.getTime()}"

    else if @asset and (@t or @combinedName)
      @child = @asset if @asset.assetableId == 0
      @child = @asset.n @combinedName if !@child and @combinedName
      @child = @asset.t @t unless @child

      if @child?.fileName and @child?.url
        return @assetUrl

      else if !@child or !@child.fileName
        @assetManager.pushRequest @asset,{
          name: @combinedName
          options: @t
          assetableType: @asset.assetableType
        }, (child) =>
          @child = child unless @isDestroyed

    null

Herd.AssetContainerComponent = Ember.Component.extend
  action: 'generateChild'
  classNames: ['asset-container']
  bgImage: true
  asset: null
  child: null
  transform: null
  t: null
  n: null
  suffix: null

  combinedName: ~>
    if @suffix
      [@n,@suffix].join '-'
    else
      @n

  +computed child asset
  isImage: ->
    return @asset?.type == 'Herd::Image' unless @child
    @child.type == 'Herd::Image' and !@bgImage

  +computed child asset
  isVideo: ->
    return @asset?.type == 'Herd::Video' unless @child
    @child.type == 'Herd::Video'

  +computed child.fileName
  assetUrl: ->
    if @child
      if Ember.empty @child.fileName
        return "https://d13yacurqjgara.cloudfront.net/users/82092/screenshots/1073359/spinner.gif"
      else
        return "#{@child?.url}?b=#{@child.updatedAt.getTime()}"

    else if @asset and (@t or @combinedName)
      @child = @asset if @asset.assetableId == 0
      @child = @asset.n @combinedName if !@child and @combinedName
      @child = @asset.t @t unless @child

      if @child?.fileName and @child?.url
        return @assetUrl

      else if !@child or !@child.fileName
        @assetManager.pushRequest @asset,{
          name: @combinedName
          options: @t
          assetableType: @asset.assetableType
        }, (child) =>
          @child = child

    null


Update guard against common Windows preprocessor definitions (#401)

* Update guard against common Windows preprocessor definitions

Rather than undefining unconditionally at the top of the file, only undefine
if a constant by one of the common names is defined.
Also, redefine the macro after the constant has been declared using the pragma
push_macro and pop_macro.
Suppress a potential warning for popping a macro that was not previously pushed.

Signed-off-by: Jacob Perron <f862f167b85d41b225785c70d70808bc7337c1fe@openrobotics.org>

* Guard against DELETE being predefined on Windows

Motivated by build errors encountered building
visualization_msgs/msg/Marker.msg.

Signed-off-by: Jacob Perron <f862f167b85d41b225785c70d70808bc7337c1fe@openrobotics.org>

@# Included from rosidl_generator_cpp/resource/idl__struct.hpp.em
@{
from rosidl_generator_cpp import create_init_alloc_and_member_lists
from rosidl_generator_cpp import escape_string
from rosidl_generator_cpp import escape_wstring
from rosidl_generator_cpp import msg_type_to_cpp
from rosidl_generator_cpp import MSG_TYPE_TO_CPP
from rosidl_parser.definition import AbstractNestedType
from rosidl_parser.definition import AbstractString
from rosidl_parser.definition import AbstractWString
from rosidl_parser.definition import ACTION_FEEDBACK_SUFFIX
from rosidl_parser.definition import ACTION_GOAL_SUFFIX
from rosidl_parser.definition import ACTION_RESULT_SUFFIX
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import BOOLEAN_TYPE
from rosidl_parser.definition import CHARACTER_TYPES
from rosidl_parser.definition import INTEGER_TYPES
from rosidl_parser.definition import NamespacedType
from rosidl_parser.definition import OCTET_TYPE
from rosidl_parser.definition import UNSIGNED_INTEGER_TYPES

message_typename = '::'.join(message.structure.namespaced_type.namespaced_name())

# Common Windows macros that may interfere with user defined constants
msvc_common_macros = ('DELETE', 'ERROR', 'NO_ERROR')
}@
@
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@# Collect necessary include directives for all members
@{
from collections import OrderedDict
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
includes = OrderedDict()
for member in message.structure.members:
    type_ = member.type
    if isinstance(type_, AbstractNestedType):
        type_ = type_.value_type
    if isinstance(type_, NamespacedType):
        if (
            type_.name.endswith(ACTION_GOAL_SUFFIX) or
            type_.name.endswith(ACTION_RESULT_SUFFIX) or
            type_.name.endswith(ACTION_FEEDBACK_SUFFIX)
        ):
            typename = type_.name.rsplit('_', 1)[0]
        else:
            typename = type_.name
        member_names = includes.setdefault(
            '/'.join((type_.namespaces + [convert_camel_case_to_lower_case_underscore(typename)])) + '__struct.hpp', [])
        member_names.append(member.name)
}@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@[if includes]@

// Include directives for member types
@[    for header_file, member_names in includes.items()]@
@[        for member_name in member_names]@
// Member '@(member_name)'
@[        end for]@
@[        if header_file in include_directives]@
// already included above
// @
@[        else]@
@{include_directives.add(header_file)}@
@[        end if]@
#include "@(header_file)"
@[    end for]@
@[end if]@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

@{
deprecated_macro_name = \
    '__'.join(['DEPRECATED', package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name])
}@
#ifndef _WIN32
# define @(deprecated_macro_name) __attribute__((deprecated))
#else
# define @(deprecated_macro_name) __declspec(deprecated)
#endif

@[for ns in message.structure.namespaced_type.namespaces]@
namespace @(ns)
{

@[end for]@
// message struct
template<class ContainerAllocator>
struct @(message.structure.namespaced_type.name)_
{
  using Type = @(message.structure.namespaced_type.name)_<ContainerAllocator>;

@{
# The creation of the constructors for messages is a bit complicated.  The goal
# is to have a constructor where the user can control how the fields of the
# message get initialized via the _init parameter to the constructor.  See
# http://design.ros2.org/articles/generated_interfaces_cpp.html#constructors
# for a detailed explanation of the different _init parameters.
init_list, alloc_list, member_list = create_init_alloc_and_member_lists(message)

def generate_default_string(membset):
    from rosidl_generator_cpp import msg_type_only_to_cpp
    from rosidl_generator_cpp import msg_type_to_cpp
    strlist = []
    for member in membset.members:
        if member.default_value is not None:
            if member.num_prealloc > 0:
                strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc))
            if isinstance(member.default_value, list):
                if all(v == member.default_value[0] for v in member.default_value):
                    # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244)
                    # For more info, see https://github.com/ros2/rosidl/issues/309
                    # TODO(jacobperron): Investigate reason for build warnings on Windows
                    # TODO(jacobperron): Write test case for this path of execution
                    strlist.append('std::fill<typename %s::iterator, %s>(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.default_value[0]))
                else:
                    for index, val in enumerate(member.default_value):
                        strlist.append('this->%s[%d] = %s;' % (member.name, index, val))
            else:
                strlist.append('this->%s = %s;' % (member.name, member.default_value))

    return strlist

def generate_zero_string(membset, fill_args):
    from rosidl_generator_cpp import msg_type_only_to_cpp
    from rosidl_generator_cpp import msg_type_to_cpp
    strlist = []
    for member in membset.members:
        if isinstance(member.zero_value, list):
            if member.num_prealloc > 0:
                strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc))
            if member.zero_need_array_override:
                strlist.append('this->%s.fill(%s{%s});' % (member.name, msg_type_only_to_cpp(member.type), fill_args))
            else:
                # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244)
                # For more info, see https://github.com/ros2/rosidl/issues/309
                # TODO(jacobperron): Investigate reason for build warnings on Windows
                strlist.append('std::fill<typename %s::iterator, %s>(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.zero_value[0]))
        else:
            strlist.append('this->%s = %s;' % (member.name, member.zero_value))
    return strlist
}@
  explicit @(message.structure.namespaced_type.name)_(rosidl_generator_cpp::MessageInitialization _init = rosidl_generator_cpp::MessageInitialization::ALL)
@[if init_list]@
  : @(',\n    '.join(init_list))
@[end if]@
  {
@[if not member_list]@
    (void)_init;
@[end if]@
@{
default_value_members = [m for m in member_list if m.members[0].default_value]
zero_value_members = [m for m in member_list if m.members[0].zero_value]
non_defaulted_zero_initialized_members = [
    m for m in member_list
    if (m.members[0].zero_value or m.members[0].zero_need_array_override) and not m.members[0].default_value
]
}@
@[if default_value_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::DEFAULTS_ONLY == _init)
    {
@[  for membset in default_value_members]@
@[    for line in generate_default_string(membset)]@
      @(line)
@[    end for]@
@[  end for]@
@[  if zero_value_members]@
    } else if (rosidl_generator_cpp::MessageInitialization::ZERO == _init) {
@[    for membset in zero_value_members]@
@[      for line in generate_zero_string(membset, '_init')]@
      @(line)
@[      end for]@
@[    end for]@
@[  end if]@
    }
@[  end if]@
@[  if non_defaulted_zero_initialized_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::ZERO == _init)
    {
@[  for membset in non_defaulted_zero_initialized_members]@
@[    for line in generate_zero_string(membset, '_init')]@
@[      if line]@
      @(line)
@[      end if]@
@[    end for]@
@[  end for]@
    }
@[end if]@
  }

  explicit @(message.structure.namespaced_type.name)_(const ContainerAllocator & _alloc, rosidl_generator_cpp::MessageInitialization _init = rosidl_generator_cpp::MessageInitialization::ALL)
@[if alloc_list]@
  : @(',\n    '.join(alloc_list))
@[end if]@
  {
@[if not member_list]@
    (void)_init;
@[end if]@
@[if not alloc_list]@
    (void)_alloc;
@[end if]@
@[if default_value_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::DEFAULTS_ONLY == _init)
    {
@[  for membset in default_value_members]@
@[    for line in generate_default_string(membset)]@
      @(line)
@[    end for]@
@[  end for]@
@[  if zero_value_members]@
    } else if (rosidl_generator_cpp::MessageInitialization::ZERO == _init) {
@[    for membset in zero_value_members]@
@[      for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[      end for]@
@[    end for]@
@[  end if]@
    }
@[end if]@
@[if non_defaulted_zero_initialized_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::ZERO == _init)
    {
@[  for membset in non_defaulted_zero_initialized_members]@
@[    for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[    end for]@
@[  end for]@
    }
@[end if]@
  }

  // field types and members
@[for member in message.structure.members]@
  using _@(member.name)_type =
    @(msg_type_to_cpp(member.type));
  _@(member.name)_type @(member.name);
@[end for]@

  // setters for named parameter idiom
@[for member in message.structure.members]@
  Type & set__@(member.name)(
    const @(msg_type_to_cpp(member.type)) & _arg)
  {
    this->@(member.name) = _arg;
    return *this;
  }
@[end for]@

  // constant declarations
@[for constant in message.constants]@
@[ if constant.name in msvc_common_macros]@
  // guard against '@(constant.name)' being predefined by MSVC by temporarily undefining it
#if defined(_WIN32)
#  if defined(@(constant.name))
#    pragma push_macro("@(constant.name)")
#    undef @(constant.name)
#  endif
#endif
@[ end if]@
@[ if isinstance(constant.type, AbstractString)]@
  static const @(MSG_TYPE_TO_CPP['string']) @(constant.name);
@[ elif isinstance(constant.type, AbstractWString)]@
  static const @(MSG_TYPE_TO_CPP['wstring']) @(constant.name);
@[ else]@
  static constexpr @(MSG_TYPE_TO_CPP[constant.type.typename]) @(constant.name) =
@[  if isinstance(constant.type, BasicType) and constant.type.typename in (*INTEGER_TYPES, *CHARACTER_TYPES, BOOLEAN_TYPE, OCTET_TYPE)]@
    @(int(constant.value))@
@[   if constant.type.typename in UNSIGNED_INTEGER_TYPES]@
u@
@[   end if];
@[  else]@
    @(constant.value);
@[  end if]@
@[ end if]@
@[ if constant.name in msvc_common_macros]@
#if defined(_WIN32)
#  pragma warning(suppress : 4602)
#  pragma pop_macro("@(constant.name)")
#endif
@[ end if]@
@[end for]@

  // pointer types
  using RawPtr =
    @(message_typename)_<ContainerAllocator> *;
  using ConstRawPtr =
    const @(message_typename)_<ContainerAllocator> *;
  using SharedPtr =
    std::shared_ptr<@(message_typename)_<ContainerAllocator>>;
  using ConstSharedPtr =
    std::shared_ptr<@(message_typename)_<ContainerAllocator> const>;

  template<typename Deleter = std::default_delete<
      @(message_typename)_<ContainerAllocator>>>
  using UniquePtrWithDeleter =
    std::unique_ptr<@(message_typename)_<ContainerAllocator>, Deleter>;

  using UniquePtr = UniquePtrWithDeleter<>;

  template<typename Deleter = std::default_delete<
      @(message_typename)_<ContainerAllocator>>>
  using ConstUniquePtrWithDeleter =
    std::unique_ptr<@(message_typename)_<ContainerAllocator> const, Deleter>;
  using ConstUniquePtr = ConstUniquePtrWithDeleter<>;

  using WeakPtr =
    std::weak_ptr<@(message_typename)_<ContainerAllocator>>;
  using ConstWeakPtr =
    std::weak_ptr<@(message_typename)_<ContainerAllocator> const>;

  // pointer types similar to ROS 1, use SharedPtr / ConstSharedPtr instead
  // NOTE: Can't use 'using' here because GNU C++ can't parse attributes properly
  typedef @(deprecated_macro_name)
    std::shared_ptr<@(message_typename)_<ContainerAllocator>>
    Ptr;
  typedef @(deprecated_macro_name)
    std::shared_ptr<@(message_typename)_<ContainerAllocator> const>
    ConstPtr;

  // comparison operators
  bool operator==(const @(message.structure.namespaced_type.name)_ & other) const
  {
@[if not message.structure.members]@
    (void)other;
@[end if]@
@[for member in message.structure.members]@
    if (this->@(member.name) != other.@(member.name)) {
      return false;
    }
@[end for]@
    return true;
  }
  bool operator!=(const @(message.structure.namespaced_type.name)_ & other) const
  {
    return !this->operator==(other);
  }
};  // struct @(message.structure.namespaced_type.name)_

// alias to use template instance with default allocator
using @(message.structure.namespaced_type.name) =
  @(message_typename)_<std::allocator<void>>;

// constant definitions
@[for c in message.constants]@
@[ if c.name in msvc_common_macros]@
// guard against '@(c.name)' being predefined by MSVC by temporarily undefining it
#if defined(_WIN32)
#  if defined(@(c.name))
#    pragma push_macro("@(c.name)")
#    undef @(c.name)
#  endif
#endif
@[ end if]@
@[ if isinstance(c.type, AbstractString)]@
template<typename ContainerAllocator>
const @(MSG_TYPE_TO_CPP['string'])
@(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name) = "@(escape_string(c.value))";
@[ elif isinstance(c.type, AbstractWString)]@
template<typename ContainerAllocator>
const @(MSG_TYPE_TO_CPP['wstring'])
@(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name) = u"@(escape_wstring(c.value))";
@[ else ]@
template<typename ContainerAllocator>
constexpr @(MSG_TYPE_TO_CPP[c.type.typename]) @(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name);
@[ end if]@
@[ if c.name in msvc_common_macros]@
#if defined(_WIN32)
#  pragma warning(suppress : 4602)
#  pragma pop_macro("@(c.name)")
#endif
@[ end if]@
@[end for]@
@
@[for ns in reversed(message.structure.namespaced_type.namespaces)]@

}  // namespace @(ns)
@[end for]@

@# Included from rosidl_generator_cpp/resource/idl__struct.hpp.em
// Protect against ERROR being predefined on Windows, in case somebody defines a
// constant by that name.
#if defined(_WIN32)
  #if defined(ERROR)
    #undef ERROR
  #endif
  #if defined(NO_ERROR)
    #undef NO_ERROR
  #endif
#endif
@
@{
from rosidl_generator_cpp import create_init_alloc_and_member_lists
from rosidl_generator_cpp import escape_string
from rosidl_generator_cpp import escape_wstring
from rosidl_generator_cpp import msg_type_to_cpp
from rosidl_generator_cpp import MSG_TYPE_TO_CPP
from rosidl_parser.definition import AbstractNestedType
from rosidl_parser.definition import AbstractString
from rosidl_parser.definition import AbstractWString
from rosidl_parser.definition import ACTION_FEEDBACK_SUFFIX
from rosidl_parser.definition import ACTION_GOAL_SUFFIX
from rosidl_parser.definition import ACTION_RESULT_SUFFIX
from rosidl_parser.definition import BasicType
from rosidl_parser.definition import BOOLEAN_TYPE
from rosidl_parser.definition import CHARACTER_TYPES
from rosidl_parser.definition import INTEGER_TYPES
from rosidl_parser.definition import NamespacedType
from rosidl_parser.definition import OCTET_TYPE
from rosidl_parser.definition import UNSIGNED_INTEGER_TYPES

message_typename = '::'.join(message.structure.namespaced_type.namespaced_name())
}@
@
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@# Collect necessary include directives for all members
@{
from collections import OrderedDict
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
includes = OrderedDict()
for member in message.structure.members:
    type_ = member.type
    if isinstance(type_, AbstractNestedType):
        type_ = type_.value_type
    if isinstance(type_, NamespacedType):
        if (
            type_.name.endswith(ACTION_GOAL_SUFFIX) or
            type_.name.endswith(ACTION_RESULT_SUFFIX) or
            type_.name.endswith(ACTION_FEEDBACK_SUFFIX)
        ):
            typename = type_.name.rsplit('_', 1)[0]
        else:
            typename = type_.name
        member_names = includes.setdefault(
            '/'.join((type_.namespaces + [convert_camel_case_to_lower_case_underscore(typename)])) + '__struct.hpp', [])
        member_names.append(member.name)
}@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@
@#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@[if includes]@

// Include directives for member types
@[    for header_file, member_names in includes.items()]@
@[        for member_name in member_names]@
// Member '@(member_name)'
@[        end for]@
@[        if header_file in include_directives]@
// already included above
// @
@[        else]@
@{include_directives.add(header_file)}@
@[        end if]@
#include "@(header_file)"
@[    end for]@
@[end if]@
@#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

@{
deprecated_macro_name = \
    '__'.join(['DEPRECATED', package_name] + list(interface_path.parents[0].parts) + [message.structure.namespaced_type.name])
}@
#ifndef _WIN32
# define @(deprecated_macro_name) __attribute__((deprecated))
#else
# define @(deprecated_macro_name) __declspec(deprecated)
#endif

@[for ns in message.structure.namespaced_type.namespaces]@
namespace @(ns)
{

@[end for]@
// message struct
template<class ContainerAllocator>
struct @(message.structure.namespaced_type.name)_
{
  using Type = @(message.structure.namespaced_type.name)_<ContainerAllocator>;

@{
# The creation of the constructors for messages is a bit complicated.  The goal
# is to have a constructor where the user can control how the fields of the
# message get initialized via the _init parameter to the constructor.  See
# http://design.ros2.org/articles/generated_interfaces_cpp.html#constructors
# for a detailed explanation of the different _init parameters.
init_list, alloc_list, member_list = create_init_alloc_and_member_lists(message)

def generate_default_string(membset):
    from rosidl_generator_cpp import msg_type_only_to_cpp
    from rosidl_generator_cpp import msg_type_to_cpp
    strlist = []
    for member in membset.members:
        if member.default_value is not None:
            if member.num_prealloc > 0:
                strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc))
            if isinstance(member.default_value, list):
                if all(v == member.default_value[0] for v in member.default_value):
                    # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244)
                    # For more info, see https://github.com/ros2/rosidl/issues/309
                    # TODO(jacobperron): Investigate reason for build warnings on Windows
                    # TODO(jacobperron): Write test case for this path of execution
                    strlist.append('std::fill<typename %s::iterator, %s>(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.default_value[0]))
                else:
                    for index, val in enumerate(member.default_value):
                        strlist.append('this->%s[%d] = %s;' % (member.name, index, val))
            else:
                strlist.append('this->%s = %s;' % (member.name, member.default_value))

    return strlist

def generate_zero_string(membset, fill_args):
    from rosidl_generator_cpp import msg_type_only_to_cpp
    from rosidl_generator_cpp import msg_type_to_cpp
    strlist = []
    for member in membset.members:
        if isinstance(member.zero_value, list):
            if member.num_prealloc > 0:
                strlist.append('this->%s.resize(%d);' % (member.name, member.num_prealloc))
            if member.zero_need_array_override:
                strlist.append('this->%s.fill(%s{%s});' % (member.name, msg_type_only_to_cpp(member.type), fill_args))
            else:
                # Specifying type for std::fill because of MSVC 14.12 warning about casting 'const int' to smaller types (C4244)
                # For more info, see https://github.com/ros2/rosidl/issues/309
                # TODO(jacobperron): Investigate reason for build warnings on Windows
                strlist.append('std::fill<typename %s::iterator, %s>(this->%s.begin(), this->%s.end(), %s);' % (msg_type_to_cpp(member.type), msg_type_only_to_cpp(member.type), member.name, member.name, member.zero_value[0]))
        else:
            strlist.append('this->%s = %s;' % (member.name, member.zero_value))
    return strlist
}@
  explicit @(message.structure.namespaced_type.name)_(rosidl_generator_cpp::MessageInitialization _init = rosidl_generator_cpp::MessageInitialization::ALL)
@[if init_list]@
  : @(',\n    '.join(init_list))
@[end if]@
  {
@[if not member_list]@
    (void)_init;
@[end if]@
@{
default_value_members = [m for m in member_list if m.members[0].default_value]
zero_value_members = [m for m in member_list if m.members[0].zero_value]
non_defaulted_zero_initialized_members = [
    m for m in member_list
    if (m.members[0].zero_value or m.members[0].zero_need_array_override) and not m.members[0].default_value
]
}@
@[if default_value_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::DEFAULTS_ONLY == _init)
    {
@[  for membset in default_value_members]@
@[    for line in generate_default_string(membset)]@
      @(line)
@[    end for]@
@[  end for]@
@[  if zero_value_members]@
    } else if (rosidl_generator_cpp::MessageInitialization::ZERO == _init) {
@[    for membset in zero_value_members]@
@[      for line in generate_zero_string(membset, '_init')]@
      @(line)
@[      end for]@
@[    end for]@
@[  end if]@
    }
@[  end if]@
@[  if non_defaulted_zero_initialized_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::ZERO == _init)
    {
@[  for membset in non_defaulted_zero_initialized_members]@
@[    for line in generate_zero_string(membset, '_init')]@
@[      if line]@
      @(line)
@[      end if]@
@[    end for]@
@[  end for]@
    }
@[end if]@
  }

  explicit @(message.structure.namespaced_type.name)_(const ContainerAllocator & _alloc, rosidl_generator_cpp::MessageInitialization _init = rosidl_generator_cpp::MessageInitialization::ALL)
@[if alloc_list]@
  : @(',\n    '.join(alloc_list))
@[end if]@
  {
@[if not member_list]@
    (void)_init;
@[end if]@
@[if not alloc_list]@
    (void)_alloc;
@[end if]@
@[if default_value_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::DEFAULTS_ONLY == _init)
    {
@[  for membset in default_value_members]@
@[    for line in generate_default_string(membset)]@
      @(line)
@[    end for]@
@[  end for]@
@[  if zero_value_members]@
    } else if (rosidl_generator_cpp::MessageInitialization::ZERO == _init) {
@[    for membset in zero_value_members]@
@[      for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[      end for]@
@[    end for]@
@[  end if]@
    }
@[end if]@
@[if non_defaulted_zero_initialized_members]@
    if (rosidl_generator_cpp::MessageInitialization::ALL == _init ||
      rosidl_generator_cpp::MessageInitialization::ZERO == _init)
    {
@[  for membset in non_defaulted_zero_initialized_members]@
@[    for line in generate_zero_string(membset, '_alloc, _init')]@
      @(line)
@[    end for]@
@[  end for]@
    }
@[end if]@
  }

  // field types and members
@[for member in message.structure.members]@
  using _@(member.name)_type =
    @(msg_type_to_cpp(member.type));
  _@(member.name)_type @(member.name);
@[end for]@

  // setters for named parameter idiom
@[for member in message.structure.members]@
  Type & set__@(member.name)(
    const @(msg_type_to_cpp(member.type)) & _arg)
  {
    this->@(member.name) = _arg;
    return *this;
  }
@[end for]@

  // constant declarations
@[for constant in message.constants]@
@[ if isinstance(constant.type, AbstractString)]@
  static const @(MSG_TYPE_TO_CPP['string']) @(constant.name);
@[ elif isinstance(constant.type, AbstractWString)]@
  static const @(MSG_TYPE_TO_CPP['wstring']) @(constant.name);
@[ else]@
  static constexpr @(MSG_TYPE_TO_CPP[constant.type.typename]) @(constant.name) =
@[  if isinstance(constant.type, BasicType) and constant.type.typename in (*INTEGER_TYPES, *CHARACTER_TYPES, BOOLEAN_TYPE, OCTET_TYPE)]@
    @(int(constant.value))@
@[   if constant.type.typename in UNSIGNED_INTEGER_TYPES]@
u@
@[   end if];
@[  else]@
    @(constant.value);
@[  end if]@
@[ end if]@
@[end for]@

  // pointer types
  using RawPtr =
    @(message_typename)_<ContainerAllocator> *;
  using ConstRawPtr =
    const @(message_typename)_<ContainerAllocator> *;
  using SharedPtr =
    std::shared_ptr<@(message_typename)_<ContainerAllocator>>;
  using ConstSharedPtr =
    std::shared_ptr<@(message_typename)_<ContainerAllocator> const>;

  template<typename Deleter = std::default_delete<
      @(message_typename)_<ContainerAllocator>>>
  using UniquePtrWithDeleter =
    std::unique_ptr<@(message_typename)_<ContainerAllocator>, Deleter>;

  using UniquePtr = UniquePtrWithDeleter<>;

  template<typename Deleter = std::default_delete<
      @(message_typename)_<ContainerAllocator>>>
  using ConstUniquePtrWithDeleter =
    std::unique_ptr<@(message_typename)_<ContainerAllocator> const, Deleter>;
  using ConstUniquePtr = ConstUniquePtrWithDeleter<>;

  using WeakPtr =
    std::weak_ptr<@(message_typename)_<ContainerAllocator>>;
  using ConstWeakPtr =
    std::weak_ptr<@(message_typename)_<ContainerAllocator> const>;

  // pointer types similar to ROS 1, use SharedPtr / ConstSharedPtr instead
  // NOTE: Can't use 'using' here because GNU C++ can't parse attributes properly
  typedef @(deprecated_macro_name)
    std::shared_ptr<@(message_typename)_<ContainerAllocator>>
    Ptr;
  typedef @(deprecated_macro_name)
    std::shared_ptr<@(message_typename)_<ContainerAllocator> const>
    ConstPtr;

  // comparison operators
  bool operator==(const @(message.structure.namespaced_type.name)_ & other) const
  {
@[if not message.structure.members]@
    (void)other;
@[end if]@
@[for member in message.structure.members]@
    if (this->@(member.name) != other.@(member.name)) {
      return false;
    }
@[end for]@
    return true;
  }
  bool operator!=(const @(message.structure.namespaced_type.name)_ & other) const
  {
    return !this->operator==(other);
  }
};  // struct @(message.structure.namespaced_type.name)_

// alias to use template instance with default allocator
using @(message.structure.namespaced_type.name) =
  @(message_typename)_<std::allocator<void>>;

// constant definitions
@[for c in message.constants]@
@[ if isinstance(c.type, AbstractString)]@
template<typename ContainerAllocator>
const @(MSG_TYPE_TO_CPP['string'])
@(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name) = "@(escape_string(c.value))";
@[ elif isinstance(c.type, AbstractWString)]@
template<typename ContainerAllocator>
const @(MSG_TYPE_TO_CPP['wstring'])
@(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name) = u"@(escape_wstring(c.value))";
@[ else ]@
template<typename ContainerAllocator>
constexpr @(MSG_TYPE_TO_CPP[c.type.typename]) @(message.structure.namespaced_type.name)_<ContainerAllocator>::@(c.name);
@[ end if]@
@[end for]@
@
@[for ns in reversed(message.structure.namespaced_type.namespaces)]@

}  // namespace @(ns)
@[end for]@


Remove bogus comments regarding instructions.

# Copyright 2011 Google Inc. All Rights Reserved.
# This file is available under the Apache license.

/$/ {
  inc(line-count)
}

# Copyright 2011 Google Inc. All Rights Reserved.
# This file is available under the Apache license.

/$/ {                                          # 4: match /$/
                                               # 5: jnm 9
  inc(line-count)                              # 6: inc line-count
}                                              # 7: ret true