<NME> doxygen_shared.css
<BEF> /* The standard CSS for doxygen 1.8.7 */

body, table, div, p, dl {
	font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
	font-size: 12px;
}

table {
    border-collapse: collapse;
}

pre, code {
    font-family: monospace;
}

p {
    margin: 1em 0;
}

dl {
    margin-bottom: 1em;
}

dd {
    margin: .25em 1em;
}

ul {
    list-style-type: square;
}

li {
    margin: 0;
    padding: .2em 0;
}

/* @group Heading Levels */

h1, h2, h3, h4 {
    font-family: "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;
    margin: 2em 0 1em 0;
}

.title {
	font-size: 150%;
}

h2.groupheader {
	font-size: 150%;
	border-bottom: 1px solid #879ECB;;
}

h3.groupheader {
	font-size: 100%;
}

h1, h2, h3, h4, h5, h6 {
	-webkit-transition: text-shadow 0.5s linear;
	-moz-transition: text-shadow 0.5s linear;
	-ms-transition: text-shadow 0.5s linear;
	-o-transition: text-shadow 0.5s linear;
	transition: text-shadow 0.5s linear;
	margin-right: 15px;
}

h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
	text-shadow: 0 0 15px cyan;
}

dt {
	font-weight: bold;
}

div.multicol {
	-moz-column-gap: 1em;
	-webkit-column-gap: 1em;
	-moz-column-count: 3;
	-webkit-column-count: 3;
}

p.startli, p.startdd {
	margin-top: 2px;
}

p.starttd {
	margin-top: 0px;
}

p.endli {
	margin-bottom: 0px;
}

p.enddd {
	margin-bottom: 4px;
}

p.endtd {
	margin-bottom: 2px;
}

/* @end */

caption {
	font-weight: bold;
}

span.legend {
        font-size: 70%;
        text-align: center;
}

h3.version {
        font-size: 90%;
        text-align: center;
}

div.qindex, div.navtab{
	background-color: #EBEFF6;
	border: 1px solid #A3B4D7;
	text-align: center;
}

div.qindex, div.navpath {
	width: 100%;
	line-height: 140%;
}

div.navtab {
	margin-right: 15px;
}

/* @group Link Styling */

a {
	color: #439DE0;
	font-weight: normal;
	text-decoration: none;
}

.contents a:visited {
	color: #439DE0;
}

a:hover {
	text-decoration: underline;
}

a.qindex {
	font-weight: bold;
}

a.qindexHL {
	font-weight: bold;
	background-color: #9CAFD4;
	color: #ffffff;
	border: 1px double #869DCA;
}

.contents a.qindexHL:visited {
        color: #ffffff;
}

a.el {
	font-weight: bold;
}

a.elRef {
}

a.code, a.code:visited, a.line, a.line:visited {
	color: #439DE0; 
}

a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
	color: #439DE0; 
}

/* @end */

dl.el {
	margin-left: -1cm;
}

pre.fragment {
        border: 1px solid #C4CFE5;
        background-color: #FBFCFD;
        padding: 4px 6px;
        margin: 4px 8px 4px 2px;
        overflow: auto;
        word-wrap: break-word;
        font-size:  9pt;
        line-height: 125%;
        font-family: sans-serif;
        font-size: 105%;
}

div.fragment {
        padding: 4px 6px;
        margin: 4px 8px 4px 2px;
	background-color: #e3e3e3;
	border: 1px solid #e3e3e3;
	font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace !important;
}

div.line {
	font-family: monospace;
    font-size: 11px;
    color: #717171;
	min-height: 13px; 
	line-height: 1.0;
	text-wrap: unrestricted;
	white-space: -moz-pre-wrap; /* Moz */
	white-space: -pre-wrap;     /* Opera 4-6 */
	white-space: -o-pre-wrap;   /* Opera 7 */
	white-space: pre-wrap;      /* CSS3  */
	word-wrap: break-word;      /* IE 5.5+ */
	text-indent: -53px;
	padding-left: 53px;
	padding-bottom: 0px;
	margin: 0px;
	-webkit-transition-property: background-color, box-shadow;
	-webkit-transition-duration: 0.5s;
	-moz-transition-property: background-color, box-shadow;
	-moz-transition-duration: 0.5s;
	-ms-transition-property: background-color, box-shadow;
	-ms-transition-duration: 0.5s;
	-o-transition-property: background-color, box-shadow;
	-o-transition-duration: 0.5s;
	transition-property: background-color, box-shadow;
	transition-duration: 0.5s;
}

div.line.glow {
	background-color: cyan;
	box-shadow: 0 0 10px cyan;
}


span.lineno {
	padding-right: 4px;
	text-align: right;
	border-right: 2px solid #0F0;
	background-color: #E8E8E8;
        white-space: pre;
}
span.lineno a {
	background-color: #D8D8D8;
}

span.lineno a:hover {
	background-color: #C8C8C8;
}

div.ah {
	background-color: black;
	font-weight: bold;
	color: #ffffff;
	margin-bottom: 3px;
	margin-top: 3px;
	padding: 0.2em;
	border: solid thin #333;
	border-radius: 0.5em;
	-webkit-border-radius: .5em;
	-moz-border-radius: .5em;
	box-shadow: 2px 2px 3px #999;
	-webkit-box-shadow: 2px 2px 3px #999;
	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
}

div.groupHeader {
	margin-left: 16px;
	margin-top: 12px;
	font-weight: bold;
}

div.groupText {
	margin-left: 16px;
	font-style: italic;
}

body {
	background-color: white;
	color: black;
        margin: 0;
}

div.contents {
	margin-top: 10px;
	margin-left: 12px;
	margin-right: 8px;
}

td.indexkey {
	background-color: #EBEFF6;
	font-weight: bold;
	border: 1px solid #C4CFE5;
	margin: 2px 0px 2px 0;
	padding: 2px 10px;
        white-space: nowrap;
        vertical-align: top;
}

td.indexvalue {
	background-color: #EBEFF6;
	border: 1px solid #C4CFE5;
	padding: 2px 10px;
	margin: 2px 0px;
}

tr.memlist {
	background-color: #EEF1F7;
}

p.formulaDsp {
	text-align: center;
}

img.formulaDsp {
	
}

img.formulaInl {
	vertical-align: middle;
}

div.center {
	text-align: center;
        margin-top: 0px;
        margin-bottom: 0px;
        padding: 0px;
}

div.center img {
	border: 0px;
}

address.footer {
	text-align: right;
	padding-right: 12px;
}

img.footer {
	border: 0px;
	vertical-align: middle;
}

/* @group Code Colorization */

span.keyword {
	color: #B30303
}

span.keywordtype {
	color: #ac3646
}

span.keywordflow {
	color: #e08000
}

span.comment {
	color: #2d499d
}

span.preprocessor {
	color: #806020
}

span.stringliteral {
	color: #002080
}

span.charliteral {
	color: #008080
}

span.vhdldigit { 
	color: #ff00ff 
}

span.vhdlchar { 
	color: #000000 
}

span.vhdlkeyword { 
	color: #700070 
}

span.vhdllogic { 
	color: #ff0000 
}

blockquote {
        background-color: #F7F8FB;
        border-left: 2px solid #9CAFD4;
        margin: 0 24px 0 4px;
        padding: 0 12px 0 16px;
}

/* @end */

/*
.search {
	color: #003399;
	font-weight: bold;
}

form.search {
	margin-bottom: 0px;
	margin-top: 0px;
}

input.search {
	font-size: 75%;
	color: #000080;
	font-weight: normal;
	background-color: #e8eef2;
}
*/

td.tiny {
	font-size: 75%;
}

.dirtab {
	padding: 4px;
	border-collapse: collapse;
	border: 1px solid #A3B4D7;
}

th.dirtab {
	background: #EBEFF6;
	font-weight: bold;
}

hr {
	height: 0px;
	border: none;
	border-top: 1px solid #4A6AAA;
}

hr.footer {
	height: 1px;
}

/* @group Member Descriptions */

table.memberdecls {
	border-spacing: 0px;
	padding: 0px;
}

.memberdecls td, .fieldtable tr {
	-webkit-transition-property: background-color, box-shadow;
	-webkit-transition-duration: 0.5s;
	-moz-transition-property: background-color, box-shadow;
	-moz-transition-duration: 0.5s;
	-ms-transition-property: background-color, box-shadow;
	-ms-transition-duration: 0.5s;
	-o-transition-property: background-color, box-shadow;
	-o-transition-duration: 0.5s;
	transition-property: background-color, box-shadow;
	transition-duration: 0.5s;
}

.memberdecls td.glow, .fieldtable tr.glow {
	background-color: cyan;
	box-shadow: 0 0 15px cyan;
}

.mdescLeft, .mdescRight,
.memItemLeft, .memItemRight,
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
	background-color: #F9FAFC;
	border: none;
	margin: 4px;
	padding: 1px 0 0 8px;
}

.mdescLeft, .mdescRight {
	padding: 0px 8px 4px 8px;
	color: #555;
}

.memSeparator {
        border-bottom: 1px solid #DEE4F0;
        line-height: 1px;
        margin: 0px;
        padding: 0px;
}

.memItemLeft, .memTemplItemLeft {
        white-space: nowrap;
}

.memItemRight {
	width: 100%;
}

.memTemplParams {
	color: #439DE0;
        white-space: nowrap;
	font-size: 80%;
}

/* @end */

/* @group Member Details */

/* Styles for detailed member documentation */

.memtemplate {
	font-size: 80%;
	color: #439DE0;
	font-weight: normal;
	margin-left: 9px;
}

.memnav {
	background-color: #EBEFF6;
	border: 1px solid #A3B4D7;
	text-align: center;
	margin: 2px;
	margin-right: 15px;
	padding: 2px;
}

.mempage {
	width: 100%;
}

.memitem {
	padding: 0;
	margin-bottom: 10px;
	margin-right: 5px;
        -webkit-transition: box-shadow 0.5s linear;
        -moz-transition: box-shadow 0.5s linear;
        -ms-transition: box-shadow 0.5s linear;
        -o-transition: box-shadow 0.5s linear;
        transition: box-shadow 0.5s linear;
        display: table !important;
        width: 100%;
}

.memitem.glow {
         box-shadow: 0 0 15px cyan;
}

.memname {
        font-weight: bold;
        margin-left: 6px;
}

.memname td {
	vertical-align: bottom;
}

.memproto, dl.reflist dt {
        border-top: 1px solid #A8B8D9;
        border-left: 1px solid #A8B8D9;
        border-right: 1px solid #A8B8D9;
        padding: 6px 0px 6px 0px;
        color: #253555;
        font-weight: bold;
        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
        background-repeat:repeat-x;
        background-color: #E2E2E2;
        /* opera specific markup */
        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
        border-top-right-radius: 4px;
        border-top-left-radius: 4px;
        /* firefox specific markup */
        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
        -moz-border-radius-topright: 4px;
        -moz-border-radius-topleft: 4px;
        /* webkit specific markup */
        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
        -webkit-border-top-right-radius: 4px;
        -webkit-border-top-left-radius: 4px;

}

.memdoc, dl.reflist dd {
        border-bottom: 1px solid #A8B8D9;      
        border-left: 1px solid #A8B8D9;      
        border-right: 1px solid #A8B8D9; 
        padding: 6px 10px 2px 10px;
        background-color: #FBFCFD;
        border-top-width: 0;
        background-image:url('nav_g.png');
        background-repeat:repeat-x;
        background-color: #FFFFFF;
        /* opera specific markup */
        border-bottom-left-radius: 4px;
        border-bottom-right-radius: 4px;
        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
        /* firefox specific markup */
        -moz-border-radius-bottomleft: 4px;
        -moz-border-radius-bottomright: 4px;
        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
        /* webkit specific markup */
        -webkit-border-bottom-left-radius: 4px;
        -webkit-border-bottom-right-radius: 4px;
        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
}

dl.reflist dt {
        padding: 5px;
}

dl.reflist dd {
        margin: 0px 0px 10px 0px;
        padding: 5px;
}

.paramkey {
	text-align: right;
}

.paramtype {
	white-space: nowrap;
}

.paramname {
	color: #602020;
	white-space: nowrap;
}
.paramname em {
	font-style: normal;
}
.paramname code {
        line-height: 14px;
}

.params, .retval, .exception, .tparams {
        margin-left: 0px;
        padding-left: 0px;
}       

.params .paramname, .retval .paramname {
        font-weight: bold;
        vertical-align: top;
}
        
.params .paramtype {
        font-style: italic;
        vertical-align: top;
}       
        
.params .paramdir {
        font-family: monospace;
        vertical-align: top;
}

table.mlabels {
	border-spacing: 0px;
}

td.mlabels-left {
	width: 100%;
	padding: 0px;
}

td.mlabels-right {
	vertical-align: bottom;
	padding: 0px;
	white-space: nowrap;
}

span.mlabels {
        margin-left: 8px;
}

span.mlabel {
        background-color: #728DC1;
        border-top:1px solid #5373B4;
        border-left:1px solid #5373B4;
        border-right:1px solid #C4CFE5;
        border-bottom:1px solid #C4CFE5;
	text-shadow: none;
	color: white;
	margin-right: 4px;
	padding: 2px 3px;
	border-radius: 3px;
	font-size: 7pt;
	white-space: nowrap;
	vertical-align: middle;
}



/* @end */

/* these are for tree view inside a (index) page */

div.directory {
        margin: 10px 0px;
        border-top: 1px solid #9CAFD4;
        border-bottom: 1px solid #9CAFD4;
        width: 100%;
}

.directory table {
        border-collapse:collapse;
}

.directory td {
        margin: 0px;
        padding: 0px;
	vertical-align: top;
}

.directory td.entry {
        white-space: nowrap;
        padding-right: 6px;
	padding-top: 3px;
}

.directory td.entry a {
        outline:none;
}

.directory td.entry a img {
        border: none;
}

.directory td.desc {
        width: 100%;
        padding-left: 6px;
	padding-right: 6px;
	padding-top: 3px;
	border-left: 1px solid rgba(0,0,0,0.05);
}

.directory tr.even {
	padding-left: 6px;
	background-color: #F7F8FB;
}

.directory img {
	vertical-align: -30%;
}

.directory .levels {
        white-space: nowrap;
        width: 100%;
        text-align: right;
        font-size: 9pt;
}

.directory .levels span {
        cursor: pointer;
        padding-left: 2px;
        padding-right: 2px;
	color: #439DE0;
}

.arrow {
    color: #9CAFD4;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    cursor: pointer;
    font-size: 80%;
    display: inline-block;
    width: 16px;
    height: 22px;
}

.icon {
    font-family: Arial, Helvetica;
    font-weight: bold;
    font-size: 12px;
    height: 14px;
    width: 16px;
    display: inline-block;
    background-color: #728DC1;
    color: white;
    text-align: center;
    border-radius: 4px;
    margin-left: 2px;
    margin-right: 2px;
}

.icona {
    width: 24px;
    height: 22px;
    display: inline-block;
}

.iconfopen {
    width: 24px;
    height: 18px;
    margin-bottom: 4px;
    background-image:url('ftv2folderopen.png');
    background-position: 0px -4px;
    background-repeat: repeat-y;
    vertical-align:top;
    display: inline-block;
}

.iconfclosed {
    width: 24px;
    height: 18px;
    margin-bottom: 4px;
    background-image:url('ftv2folderclosed.png');
    background-position: 0px -4px;
    background-repeat: repeat-y;
    vertical-align:top;
    display: inline-block;
}

.icondoc {
    width: 24px;
    height: 18px;
    margin-bottom: 4px;
    background-image:url('ftv2doc.png');
    background-position: 0px -4px;
    background-repeat: repeat-y;
    vertical-align:top;
    display: inline-block;
}

table.directory {
    font: 400 12px Roboto,sans-serif;
}

/* @end */

div.dynheader {
        margin-top: 8px;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

address {
	font-style: normal;
	color: #2A3D61;
}

table.doxtable {
	border-collapse:collapse;
        margin-top: 4px;
        margin-bottom: 4px;
}

table.doxtable td, table.doxtable th {
	border: 1px solid #2D4068;
	padding: 3px 7px 2px;
}

table.doxtable th {
	background-color: #374F7F;
	color: #FFFFFF;
	font-size: 110%;
	padding-bottom: 4px;
	padding-top: 5px;
}

table.fieldtable {
        /*width: 100%;*/
        margin-bottom: 10px;
        border: 1px solid #A8B8D9;
        border-spacing: 0px;
        -moz-border-radius: 4px;
        -webkit-border-radius: 4px;
        border-radius: 4px;
        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
}

.fieldtable td, .fieldtable th {
        padding: 3px 7px 2px;
}

.fieldtable td.fieldtype, .fieldtable td.fieldname {
        white-space: nowrap;
        border-right: 1px solid #A8B8D9;
        border-bottom: 1px solid #A8B8D9;
        vertical-align: top;
}

.fieldtable td.fieldname {
        padding-top: 3px;
}

.fieldtable td.fielddoc {
        border-bottom: 1px solid #A8B8D9;
        /*width: 100%;*/
}

.fieldtable td.fielddoc p:first-child {
        margin-top: 0px;
}       
        
.fieldtable td.fielddoc p:last-child {
        margin-bottom: 2px;
}

.fieldtable tr:last-child td {
        border-bottom: none;
}

.fieldtable th {
        background-image:url('nav_f.png');
        background-repeat:repeat-x;
        background-color: #E2E8F2;
        font-size: 90%;
        color: #253555;
        padding-bottom: 4px;
        padding-top: 5px;
        text-align:left;
        -moz-border-radius-topleft: 4px;
        -moz-border-radius-topright: 4px;
        -webkit-border-top-left-radius: 4px;
        -webkit-border-top-right-radius: 4px;
        border-top-left-radius: 4px;
        border-top-right-radius: 4px;
        border-bottom: 1px solid #A8B8D9;
}
/* ADDITIONS */
.tabs, .tabs2, .tabs3 {
    background: #F6F6F6 !important;
    border-bottom: 1px solid #eaeaea;
    width: 100%;
    z-index: 101;
    font-size: 110%;
}

.tabs a, .tabs2 a{
    text-align: center;
}

.tabs2 {
    font-size: 90%;
}

.tablist {
    margin: 0;
    padding: 0;
    display: table;
}

.tablist li {
    float: left;
    display: table-cell;
    line-height: 36px;
    list-style: none;
    background: inherit;
    padding: 0;
}

.tablist a {
    display: block;
    padding: 0 20px;
    font-weight: bold;
    text-decoration: none;
    outline: none;
    background: none;
    color: #444;
    border-right: 1px solid #eaeaea;
}

.tablist a:hover {
    background: inherit;
    text-decoration: none;
    text-shadow: none;
    color: gray;
}

.tabs3 {
    font-size: 100%;
    max-height: 20px;
    line-height: 0px;
}

.tabs3 li {
    padding: 0px;
    margin: 0px;
    line-height: 20px;
}

.tabs3 .tablist a {
    padding: 0 10px;
    height: 20px;
    padding-top: 0px;
    margin-top: 0px;
}

.tablist li.current a {
    background: #ddd;
    color: #444;
    text-shadow: none;
}

.tabs2 li{
     padding: 0px;
    margin: 0px;
    line-height: 30px;
}


#nav-tree .children_ul {
    margin:0;
    padding:1px;
}

#nav-tree ul {
    list-style:none outside none;
    margin:0px;
    padding: 5px;
}

#nav-tree li {
    white-space:nowrap;
    margin:0px;
    padding-top: 1px;
}

#nav-tree .plus {
    margin:0px;
}

#nav-tree .selected {
    background-color: #9CAFD4 !important;
    border-top: none;
    background-image: none;
}

#nav-tree img {
  margin:0px;
  padding:0px;
  border:0px;
  -webkit-filter: grayscale(1);
  width: 8px;
  height: 11px;
  margin-top: -4px;
}

#nav-tree .selected img {
     -webkit-filter: grayscale(0);
}

#nav-tree a {
  text-decoration:none;
  padding:0px;
  margin:0px;
  outline:none;
  color: #333;
}

#nav-tree .label {
  margin:0px;
  padding:0px;
}

#nav-tree .label a {
  padding:2px;
}

#nav-tree .selected a {
  text-decoration:none;
  padding:2px;
  margin:0px;
  color: white;
  text-shadow: none;
  font-weight: bold;
}

#nav-tree .children_ul {
  margin:0px;
  padding:0px;
}

#nav-tree .item {
  margin:0px;
  padding:0px;
  height:16px;
}

#nav-tree {
  padding: 0px 0px;
  background: white;
  font-size:14px;
  overflow:auto;
  padding-right: 0px !important;
  margin-right: -5px !important;
}

.ui-resizable .ui-resizable-handle {
  display:block;
  background-image: none !important;
}

.ui-resizable-e {
  background: #eaeaea !important;
  cursor:e-resize;
  height:100%;
  right:0;
  top:0;
  width: 1px !important;
}

.ui-resizable-handle {
  display:none;
  font-size:0.1px;
  position:absolute;
  z-index:1;
}

.tabsearch {
	top: 0px;
	left: 10px;
	height: 36px;
	background-color: red;
	z-index: 101;
	overflow: hidden;
	font-size: 13px;
}

.navpath ul
{
	font-size: 9px;
	background-color: #b7b7b7;
	background: -webkit-gradient(linear,left top,left bottom,from(whitesmoke),to(#CCC));
	background-repeat:repeat-x;
	background-position: 0 0px;
	height:30px;
	line-height:30px;
	color:#8AA0CC;
	border:solid 1px #C2CDE4;
	overflow:hidden;
	margin:0px;
	padding:0px;
}

.navpath li
{
	list-style-type:none;
	float:left;
	padding-left:10px;
	padding-right:15px;
	background-image:url('bc_s.png');
	background-repeat:no-repeat;
	background-position:right;
	color:#364D7C;
}

.navpath li.navelem a
{
	height:32px;
	display:block;
	text-decoration: none;
	outline: none;
	color: #283A5D;
	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
	text-decoration: none;        
}

.navpath li.navelem a:hover
{
	color:#6884BD;
}

.navpath li.footer
{
        list-style-type:none;
        float:right;
        padding-left:10px;
        padding-right:15px;
        background-image:none;
        background-repeat:no-repeat;
        background-position:right;
        color:#364D7C;
        font-size: 8pt;
}


div.summary
{
	float: right;
	font-size: 8pt;
	padding-right: 5px;
	width: 50%;
	text-align: right;
}       

div.summary a
{
	white-space: nowrap;
}

div.ingroups
{
	font-size: 8pt;
	width: 50%;
	text-align: left;
}

div.ingroups a
{
	white-space: nowrap;
}

div.header
{
        background-image:url('nav_h.png');
        background-repeat:repeat-x;
	background-color: #F9FAFC;
	margin:  0px;
	border-bottom: 1px solid #C4CFE5;
}

div.headertitle
{
	padding: 5px 5px 5px 10px;
}

dl
{
        padding: 0 0 0 10px;
}

/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
dl.section
{
	margin-left: 0px;
	padding-left: 0px;
}

dl.note
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #D0C000;
}

dl.warning, dl.attention
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #FF0000;
}

dl.pre, dl.post, dl.invariant
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #00D000;
}

dl.deprecated
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #505050;
}

dl.todo
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #00C0E0;
}

dl.test
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #3030E0;
}

dl.bug
{
        margin-left:-7px;
        padding-left: 3px;
        border-left:4px solid;
        border-color: #C08050;
}

dl.section dd {
	margin-bottom: 6px;
}


#projectlogo
{
	text-align: center;
	vertical-align: bottom;
	border-collapse: separate;
}
 
#projectlogo img
{ 
	border: 0px none;
}
 
#projectname
{
	font: 300% Tahoma, Arial,sans-serif;
	margin: 0px;
	padding: 2px 0px;
}
    
#projectbrief
{
	font: 120% Tahoma, Arial,sans-serif;
	margin: 0px;
	padding: 0px;
}

#projectnumber
{
	font: 75% Tahoma, Arial,sans-serif;
	margin: 0px;
	padding: 0px;
}

.image
{
        text-align: center;
}

.dotgraph
{
        text-align: center;
}

.mscgraph
{
        text-align: center;
}

.diagraph
{
        text-align: center;
}

.caption
{
	font-weight: bold;
}

div.zoom
{
	border: 1px solid #90A5CE;
}

dl.citelist {
        margin-bottom:50px;
}

dl.citelist dt {
        color:#334975;
        float:left;
        font-weight:bold;
        margin-right:10px;
        padding:5px;
}

dl.citelist dd {
        margin:2px 0;
        padding:5px 0;
}

div.toc {
        padding: 14px 25px;
        background-color: #F4F6FA;
        border: 1px solid #D8DFEE;
        border-radius: 7px 7px 7px 7px;
        float: right;
        height: auto;
        margin: 0 20px 10px 10px;
        width: 200px;
}

div.toc li {
        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
        margin-top: 5px;
        padding-left: 10px;
        padding-top: 2px;
}

div.toc h3 {
        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
	color: #439DE0;
        border-bottom: 0 none;
        margin: 0;
}

div.toc ul {
        list-style: none outside none;
        border: medium none;
        padding: 0px;
}       

div.toc li.level1 {
        margin-left: 0px;
}

div.toc li.level2 {
        margin-left: 15px;
}

div.toc li.level3 {
        margin-left: 30px;
}

div.toc li.level4 {
        margin-left: 45px;
}

.inherit_header {
        font-weight: bold;
        color: gray;
        cursor: pointer;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.inherit_header td {
        padding: 6px 0px 2px 5px;
}

.inherit {
        display: none;
}

tr.heading h2 {
        margin-top: 12px;
        margin-bottom: 4px;
}

/* tooltip related style info */

.ttc {
        position: absolute;
        display: none;
}

#powerTip {
	cursor: default;
	white-space: nowrap;
	background-color: white;
	border: 1px solid gray;
	border-radius: 4px 4px 4px 4px;
	box-shadow: 1px 1px 7px gray;
	display: none;
	font-size: smaller;
	max-width: 80%;
	opacity: 0.9;
	padding: 1ex 1em 1em;
	position: absolute;
	z-index: 2147483647;
}

#powerTip div.ttdoc {
        color: grey;
	font-style: italic;
}

#powerTip div.ttname a {
        font-weight: bold;
}

#powerTip div.ttname {
        font-weight: bold;
}

#powerTip div.ttdeci {
        color: #006318;
}

#powerTip div {
        margin: 0px;
        padding: 0px;
        font: 12px/16px Roboto,sans-serif;
}

#powerTip:before, #powerTip:after {
	content: "";
	position: absolute;
	margin: 0px;
}

#powerTip.n:after,  #powerTip.n:before,
#powerTip.s:after,  #powerTip.s:before,
#powerTip.w:after,  #powerTip.w:before,
#powerTip.e:after,  #powerTip.e:before,
#powerTip.ne:after, #powerTip.ne:before,
#powerTip.se:after, #powerTip.se:before,
#powerTip.nw:after, #powerTip.nw:before,
#powerTip.sw:after, #powerTip.sw:before {
	border: solid transparent;
	content: " ";
	height: 0;
	width: 0;
	position: absolute;
}

#powerTip.n:after,  #powerTip.s:after,
#powerTip.w:after,  #powerTip.e:after,
#powerTip.nw:after, #powerTip.ne:after,
#powerTip.sw:after, #powerTip.se:after {
	border-color: rgba(255, 255, 255, 0);
}

#powerTip.n:before,  #powerTip.s:before,
#powerTip.w:before,  #powerTip.e:before,
#powerTip.nw:before, #powerTip.ne:before,
#powerTip.sw:before, #powerTip.se:before {
	border-color: rgba(128, 128, 128, 0);
}

#powerTip.n:after,  #powerTip.n:before,
#powerTip.ne:after, #powerTip.ne:before,
#powerTip.nw:after, #powerTip.nw:before {
	top: 100%;
}

#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
	border-top-color: #ffffff;
	border-width: 10px;
	margin: 0px -10px;
}
#powerTip.n:before {
	border-top-color: #808080;
	border-width: 11px;
	margin: 0px -11px;
}
#powerTip.n:after, #powerTip.n:before {
	left: 50%;
}

#powerTip.nw:after, #powerTip.nw:before {
	right: 14px;
}

#powerTip.ne:after, #powerTip.ne:before {
	left: 14px;
}

#powerTip.s:after,  #powerTip.s:before,
#powerTip.se:after, #powerTip.se:before,
#powerTip.sw:after, #powerTip.sw:before {
	bottom: 100%;
}

#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
	border-bottom-color: #ffffff;
	border-width: 10px;
	margin: 0px -10px;
}

#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
	border-bottom-color: #808080;
	border-width: 11px;
	margin: 0px -11px;
}

#powerTip.s:after, #powerTip.s:before {
	left: 50%;
}

#powerTip.sw:after, #powerTip.sw:before {
	right: 14px;
}

#powerTip.se:after, #powerTip.se:before {
	left: 14px;
}

#powerTip.e:after, #powerTip.e:before {
	left: 100%;
}
#powerTip.e:after {
	border-left-color: #ffffff;
	border-width: 10px;
	top: 50%;
	margin-top: -10px;
}
#powerTip.e:before {
	border-left-color: #808080;
	border-width: 11px;
	top: 50%;
	margin-top: -11px;
}

#powerTip.w:after, #powerTip.w:before {
	right: 100%;
}
#powerTip.w:after {
	border-right-color: #ffffff;
	border-width: 10px;
	top: 50%;
	margin-top: -10px;
}
#powerTip.w:before {
	border-right-color: #808080;
	border-width: 11px;
	top: 50%;
	margin-top: -11px;
}

@media print
{
  #top { display: none; }
  #side-nav { display: none; }
  #nav-path { display: none; }
  body { overflow:visible; }
  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
  .summary { display: none; }
  .memitem { page-break-inside: avoid; }
  #doc-content
  {
    margin-left:0 !important;
    height:auto !important;
    width:auto !important;
    overflow:inherit;
    display:inline;
  }
}


<MSG> Merge branch 'master' into data_adapter_classes

<DFF> @@ -10,7 +10,7 @@ table {
 }
 
 pre, code {
-    font-family: monospace;
+	font-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
 }
 
 p {
@@ -197,15 +197,16 @@ pre.fragment {
 div.fragment {
         padding: 4px 6px;
         margin: 4px 8px 4px 2px;
-	background-color: #e3e3e3;
-	border: 1px solid #e3e3e3;
-	font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace !important;
+	background-color: #f3f3f3;
+	border: 1px solid #f3f3f3;
 }
 
 div.line {
-	font-family: monospace;
+    /* This is the font used for code blocks (@code). Menlo is on OSX, Consolas
+     * is on Windows. */
+	font-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
     font-size: 11px;
-    color: #717171;
+    /* color: #000000; */ /* use default font color for code */
 	min-height: 13px; 
 	line-height: 1.0;
 	text-wrap: unrestricted;

{'commit': 'diff --git a/.travis.yml b/.travis.yml\nindex 0b1ddbae0..4a6c8f592 100644\n--- a/.travis.yml\n+++ b/.travis.yml\n@@ -42,18 +42,16 @@ addons:\n     sources:\n       # For gcc >= 4.8\n       - ubuntu-toolchain-r-test\n+      # for clang\n+      - llvm-toolchain-precise-3.5\n       # For cmake >= 2.8.8 (for CMakePackageConfigHelpers)\n       - kubuntu-backports\n     packages:\n       - cmake\n       # For Simbody.\n       - liblapack-dev\n-      # C++11 on Ubuntu. Update to gcc 4.8, which provides full C++11 support.  We\n-      # use this script because if building Simbody with C++11, we need gcc-4.8,\n-      # and the Travis Ubuntu 12.04 machines have an older version of gcc. Even if\n-      # building with Clang, we need the newer libstdc++ that we get by updating to\n-      # gcc-4.8.  See https://github.com/travis-ci/travis-ci/issues/979.\n-      - g++-4.8\n+      - g++-4.9\n+      - clang-3.5\n       # In case someone wants to check for memory leaks.\n       - valgrind\n       # To build doxygen documentation.\n@@ -68,7 +66,8 @@ before_install:\n   ## Set up environment variables.\n   # Only if compiling with gcc, update environment variables\n   # to use the new gcc.\n-  - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi\n+  - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi\n+  - if [[ "$TRAVIS_OS_NAME" = "linux" && "$CXX" = "clang++" ]]; then export CXX="clang++-3.5" CC="clang-3.5"; fi\n   \n   ## Temporary hack to find libblas and liblapack.\n   # TODO. Currently Simbody is using Travis CI\'s Ubuntu 14.04 VMs, which link with \n@@ -133,7 +132,7 @@ before_install:\n install:\n   - mkdir ~/opensim-core-build && cd ~/opensim-core-build\n   # Configure OpenSim.\n-  - cmake $TRAVIS_BUILD_DIR -DBUILD_JAVA_WRAPPING=$WRAP -DBUILD_PYTHON_WRAPPING=$WRAP -DSWIG_EXECUTABLE=$HOME/swig/bin/swig -DSIMBODY_HOME=~/simbody -DOPENSIM_DEPENDENCIES_DIR=$OPENSIM_DEPENDENCIES_INSTALL_DIR -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_INSTALL_PREFIX=$OPENSIM_HOME -DCMAKE_BUILD_TYPE=$BTYPE -DDOXYGEN_EXECUTABLE=$HOME/doxygen/doxygen-1.8.10/bin/doxygen -DOPENSIM_DOXYGEN_USE_MATHJAX=off -DOPENSIM_SIMBODY_DOXYGEN_LOCATION="https://simtk.org/api_docs/simbody/latest/"\n+  - cmake $TRAVIS_BUILD_DIR -DBUILD_JAVA_WRAPPING=$WRAP -DBUILD_PYTHON_WRAPPING=$WRAP -DSWIG_EXECUTABLE=$HOME/swig/bin/swig -DSIMBODY_HOME=~/simbody -DOPENSIM_DEPENDENCIES_DIR=$OPENSIM_DEPENDENCIES_INSTALL_DIR -DCMAKE_INSTALL_PREFIX=$OPENSIM_HOME -DCMAKE_BUILD_TYPE=$BTYPE -DDOXYGEN_EXECUTABLE=$HOME/doxygen/doxygen-1.8.10/bin/doxygen -DOPENSIM_DOXYGEN_USE_MATHJAX=off -DOPENSIM_SIMBODY_DOXYGEN_LOCATION="https://simtk.org/api_docs/simbody/latest/"\n   # Build OpenSim.\n   # Build java and python C++ wrapper separately to avoid going over the memory limit.\n   - if [[ "$WRAP" = "on" ]]; then make -j$NPROC osimTools osimJavaJNI PythonBindings; fi\ndiff --git a/Applications/CMC/test/CMakeLists.txt b/Applications/CMC/test/CMakeLists.txt\nindex 54006bff9..31feff666 100644\n--- a/Applications/CMC/test/CMakeLists.txt\n+++ b/Applications/CMC/test/CMakeLists.txt\n@@ -7,3 +7,5 @@ OpenSimAddTests(\n     DATAFILES ${TEST_FILES}\n     LINKLIBS osimTools\n     )\n+\n+OpenSimCopySharedTestFiles(std_subject01_walk1_states.sto)\ndiff --git a/Bindings/OpenSimHeaders_simulation.h b/Bindings/OpenSimHeaders_simulation.h\nindex ad7685b10..9de4be4da 100644\n--- a/Bindings/OpenSimHeaders_simulation.h\n+++ b/Bindings/OpenSimHeaders_simulation.h\n@@ -138,5 +138,7 @@\n #include <OpenSim/Simulation/CoordinateReference.h>\n #include <OpenSim/Simulation/InverseKinematicsSolver.h>\n \n+#include <OpenSim/Simulation/StatesTrajectory.h>\n+\n #endif // OPENSIM_OPENSIM_HEADERS_SIMULATION_H_\n \ndiff --git a/Bindings/Python/swig/python_simulation.i b/Bindings/Python/swig/python_simulation.i\nindex 8119806b0..f7b8f5030 100644\n--- a/Bindings/Python/swig/python_simulation.i\n+++ b/Bindings/Python/swig/python_simulation.i\n@@ -116,6 +116,41 @@ EXPOSE_JOINT_CONSTRUCTORS_HELPER(PlanarJoint);\n // ========\n // None.\n \n+// Pythonic operators\n+// ==================\n+// Allow iterating through a StatesTrajectory.\n+// This extend block must appear before the %template call in simulation.i.\n+\n+// TODO remove.\n+%rename(_getBetween) OpenSim::StatesTrajectory::getBetween;\n+\n+%extend OpenSim::StatesTrajectory {\n+%pythoncode %{\n+\n+    def __iter__(self):\n+        """Get an iterator for this Set, to be used as such (where `states` is\n+        the StatesTrajectory object)::\n+           \n+            for state in states:\n+                model.calcMassCenterPosition(state)\n+        """\n+        it = self.begin()\n+        while it != self.end():\n+            yield it.next()\n+\n+    def getBetween(self, *args, **kwargs):\n+        iter_range = self._getBetween(*args, **kwargs)\n+        it = iter_range.begin()\n+        while it != iter_range.end():\n+            yield it.next()\n+%}\n+};\n+\n+// TODO we already made a StdVectorState in simbody.i, but this is required\n+// to create type traits for the simulation module. Ideally, we would not need\n+// the following line:\n+%template(_StdVectorState) std::vector<SimTK::State>;\n+\n \n // Include all the OpenSim code.\n // =============================\n@@ -152,3 +187,12 @@ SET_ADOPT_HELPER(Analysis);\n         return self.appendNative(aForce)\n %}\n };\n+\n+// Pythonic operators\n+// ==================\n+// Allow indexing operator in python (e.g., states[i]).\n+%extend OpenSim::StatesTrajectory {\n+    const SimTK::State&  __getitem__(int i) const {\n+        return $self->get(i);\n+    }\n+};\ndiff --git a/Bindings/Python/tests/test_states_trajectory.py b/Bindings/Python/tests/test_states_trajectory.py\nnew file mode 100644\nindex 000000000..0f6dd94cd\n--- /dev/null\n+++ b/Bindings/Python/tests/test_states_trajectory.py\n@@ -0,0 +1,140 @@\n+import os\n+import unittest\n+\n+import opensim as osim\n+\n+test_dir = os.path.join(os.path.dirname(os.path.abspath(osim.__file__)),\n+                        \'tests\')\n+\n+# TODO add more tests of the integrity checks.\n+\n+class TestStatesTrajectory(unittest.TestCase):\n+    states_sto_fname = "test_states_trajectory_gait1018_states.sto"\n+    def test_index_and_iterator(self):\n+\n+        if os.path.exists(self.states_sto_fname):\n+            os.remove(self.states_sto_fname)\n+\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        model.initSystem()\n+\n+        forward = osim.ForwardTool()\n+        forward.setModel(model)\n+        forward.setName(\'test_states_trajectory_gait1018\')\n+        forward.setFinalTime(0.1)\n+        forward.run()\n+\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, self.states_sto_fname)\n+\n+        # Test indexing into the states container.\n+        model.getTotalMass(states[0])\n+\n+        count = 0\n+        for i in range(states.getSize()):\n+            model.calcMassCenterVelocity(states.get(i))\n+            count += 1\n+\n+        # Test iterator.\n+        count_iter = 0\n+        for state in states:\n+            model.calcMassCenterPosition(state)\n+            count_iter += 1\n+        assert count == count_iter\n+\n+    def test_modify_states(self):\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        model.initSystem()\n+\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, self.states_sto_fname)\n+\n+        states[0].setTime(4)\n+        assert states[0].getTime() == 4\n+\n+        self.assertNotAlmostEqual(model.getStateVariableValue(states[2],\n+                "ground_pelvis/pelvis_tilt/value"), 8)\n+        model.setStateVariableValue(states[2],\n+                "ground_pelvis/pelvis_tilt/value", 8)\n+        self.assertAlmostEqual(model.getStateVariableValue(states[2],\n+                "ground_pelvis/pelvis_tilt/value"), 8)\n+\n+        # Assigning is not allowed, since it easily allows people to violate\n+        # the ordering of the trajectory.\n+        # Also, the assignment `states.upd(5) = states[2]` is not possible in\n+        # Python (\'can\'t assign to function call\').\n+        def test_setitem():\n+            states[5] = states[2]\n+        self.assertRaises(TypeError, test_setitem)\n+\n+\n+    def test_states_storage_optional_arguments(self):\n+        # Try all combinations of optional arguments, just to ensure the\n+        # wrapping works.\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        sto = osim.Storage(self.states_sto_fname)\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, sto)\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, sto, False, False)\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, sto, False, True)\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, sto, True, False)\n+        states = osim.StatesTrajectory.createFromStatesStorage(\n+                model, sto, True, True)\n+\n+    def test_populate_trajectory(self):\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        state = model.initSystem()\n+        states = osim.StatesTrajectory()\n+        states.append(state)\n+        state.setTime(1.0)\n+        states.append(state)\n+\n+        self.assertEqual(states.getSize(), 2)\n+        self.assertEqual(states[1].getTime(), 1.0)\n+\n+    def test_out_of_range(self):\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        state = model.initSystem()\n+        states = osim.StatesTrajectory()\n+        states.append(state)\n+        state.setTime(1.0)\n+        states.append(state)\n+\n+        # TODO this exception message could be better...\n+        self.assertRaises(RuntimeError, lambda: states[2].getTime())\n+\n+    def test_integrity_checks(self):\n+        model = osim.Model(os.path.join(test_dir,\n+            "gait10dof18musc_subject01.osim"))\n+        state = model.initSystem()\n+        states = osim.StatesTrajectory()\n+        states.append(state)\n+        state.setTime(1.0)\n+        states.append(state)\n+        self.assertTrue(states.isNondecreasingInTime())\n+        self.assertTrue(states.isConsistent())\n+        self.assertTrue(states.hasIntegrity())\n+\n+        # Cannot append a state with an earlier time than the last one.\n+        state.setTime(0.5)\n+        self.assertRaises(RuntimeError, states.append, state)\n+\n+        # However, since python doesn\'t have constness, we can edit the time of\n+        # a state in the trajectory.\n+        state.setTime(1.5)\n+        states.append(state)\n+        self.assertTrue(states.isNondecreasingInTime())\n+        states.back().setTime(0.25)\n+        self.assertFalse(states.isNondecreasingInTime())\n+        self.assertTrue(states.isConsistent())\n+        self.assertFalse(states.hasIntegrity())\n+\n+        # TODO check violating isConsistent() (might need a different model).\ndiff --git a/Bindings/simbody.i b/Bindings/simbody.i\nindex 4901f71c4..501a1a4a7 100644\n--- a/Bindings/simbody.i\n+++ b/Bindings/simbody.i\n@@ -3,6 +3,9 @@\n %include <SimTKcommon.h>\n \n %include <SimTKcommon/Constants.h>\n+\n+%include <SimTKcommon/internal/IteratorRange.h>\n+\n %include <SWIGSimTK/Vec.h>\n \n // Vec3\n@@ -91,3 +94,5 @@ namespace SimTK {\n // State & Stage\n %include <SWIGSimTK/Stage.h>\n %include <SWIGSimTK/State.h>\n+// Used for StatesTrajectory iterating.\n+%template(StdVectorState) std::vector<SimTK::State>;\ndiff --git a/Bindings/simulation.i b/Bindings/simulation.i\nindex 85dd4dc57..1cf1596f4 100644\n--- a/Bindings/simulation.i\n+++ b/Bindings/simulation.i\n@@ -197,6 +197,11 @@\n %include <OpenSim/Simulation/AssemblySolver.h>\n %include <OpenSim/Simulation/InverseKinematicsSolver.h>\n \n+%include <OpenSim/Simulation/StatesTrajectory.h>\n+// This enables iterating using the getBetween() method.\n+%template(IteratorRangeStatesTrajectoryIterator) \n+    SimTK::IteratorRange<OpenSim::StatesTrajectory::const_iterator>;\n+\n // Iterators.\n // TODO rename to singular form.\n %template(FramesList) OpenSim::ComponentList<OpenSim::Frame>;\ndiff --git a/CHANGELOG.md b/CHANGELOG.md\nindex 14e75f429..35e44803d 100644\n--- a/CHANGELOG.md\n+++ b/CHANGELOG.md\n@@ -11,7 +11,7 @@ This is not a comprehensive list of changes but rather a hand-curated collection\n v4.0 (in development)\n =====================\n \n-Converting from v3.2 to v4.0\n+Converting from v3.x to v4.0\n -----------------------------\n - The Actuator class has been renamed to ScalarActuator (and Actuator_ has been renamed to Actuator) (PR #126).\n   If you have subclassed from Actuator, you must now subclass from ScalarActuator.\n@@ -50,6 +50,7 @@ New Classes\n - Connections to Bodies upgraded to PhysicalFrames and locations on these frames are now represented by PhysicalOffsetFrame (PR #370)\n - Joints were refactored so that the base Joint manages the parent and child frame connections, including the definition of local PhysicalOffsetFrames to handle offsets defined as separate location and orientation properties. (PR #589)  \n - The WeldConstraint and BushingForces (BushingForce, CoupledBushingForce, FunctionBasedBushingForce, and ExpressionBasedBushingForce) were similarly unified (like Joints) to handle the two Frames that these classes require to operate. A LinkTwoFrames intermediate class was introduced to house the common operations. Convenience constructors for WeldConstraint and BushingFrames were affected and now require the name of the Component as the first argument. (PR #649)\n+- The new StatesTrajectory class allows users to load an exact representation of previously-computed states from a file. (PR #730)\n \n \n Python\ndiff --git a/CONTRIBUTING.md b/CONTRIBUTING.md\nindex b126978ad..68b1be02d 100644\n--- a/CONTRIBUTING.md\n+++ b/CONTRIBUTING.md\n@@ -224,7 +224,8 @@ We have some conventional starting verbs; you should use the same ones when they\n `realize` | Initiate state-dependent computations and cache results internally; no result returned.\n `add`     | Add the object (Component) to an internal list of references. Should not take over ownership. \n `adopt`   | Take over ownership (e.g., `Set::adoptAndAppend()`).\n-`extend`  | A virtual method intended to extend a defining capability of a Base class. The first line of the derived class implementation must be `Super::extend<DoSomething>()`. For example, a ModelComponent knows how to ``connectToModel``, but the details of how each concrete ModelComponent type does this is implemented by the derived class.\n+`extend`  | A virtual method intended to extend a defining capability of a Base class; can either be pure virtual or not. The first line of the derived class implementation must be `Super::extend<DoSomething>()`. For example, a ModelComponent knows how to ``connectToModel``, but the details of how each concrete ModelComponent type does this is implemented by the derived class.\n+`implement` | A virtual method intended to implement a *pure* virtual function of a Base class. The derived class\'s implementation does *not* call any method on `Super`.\n \n ### ``throw`` and ``return`` are not functions\n \ndiff --git a/OpenSim/Common/Component.cpp b/OpenSim/Common/Component.cpp\nindex 3c415dd51..cc35a18df 100644\n--- a/OpenSim/Common/Component.cpp\n+++ b/OpenSim/Common/Component.cpp\n@@ -820,9 +820,9 @@ setDiscreteVariableValue(SimTK::State& s, const std::string& name, double value)\n     }\n }\n \n-void Component::constructOutputForStateVariable(const std::string& name)\n+bool Component::constructOutputForStateVariable(const std::string& name)\n {\n-    constructOutput<double>(name,\n+    return constructOutput<double>(name,\n             std::bind(&Component::getStateVariableValue,\n                 this, std::placeholders::_1, name),\n             SimTK::Stage::Model);\ndiff --git a/OpenSim/Common/Component.h b/OpenSim/Common/Component.h\nindex 3c079ee14..19d5e48e6 100644\n--- a/OpenSim/Common/Component.h\n+++ b/OpenSim/Common/Component.h\n@@ -1339,81 +1339,6 @@ template <class T> friend class ComponentMeasure;\n             = SimTK::ClonePtr<AbstractInput>(new Input<T>(name, requiredAtStage));\n     }\n \n-    /**\n-       A convenient way to construct an Output.  Here, we assume the following\n-       about componentMemberFunction, the function that returns the output:\n-\n-           -# It is a member function of \\a this Component.\n-           -# The member function is const.\n-           -# It takes only one input, which is const SimTK::State&\n-      \n-       If these are not true for your case, then use the more general method\n-       %Component::constructOutput(const std::string&,\n-                                  const std::function<T(const SimTK:State&)>,\n-                                  const SimTK::Stage&).\n-      \n-       Here\'s an example. Say your Component has a method calcForce:\n-        @code\n-        constructOutput<SimTK::Vec3>("force", &MyComponent::calcForce,\n-                SimTK::Stage::Velocity);\n-        @endcode\n-\n-       @see constructOutputForStateVariable()\n-     */\n-#ifndef SWIG // SWIG can\'t parse the const at the end of the second argument.\n-    template <typename T, typename Class>\n-    void constructOutput(const std::string& name,\n-            T(Class::*const componentMemberFunction)(const SimTK::State&) const,\n-            const SimTK::Stage& dependsOn = SimTK::Stage::Acceleration) {\n-        // The `const` in `Class::*const componentMemberFunction` means this\n-        // function can\'t assign componentMemberFunction to some other function\n-        // pointer. This is unlikely, since that function would have to match\n-        // the same template parameters (T and Class).\n-        constructOutput<T>(name, std::bind(componentMemberFunction,\n-                    static_cast<Class*>(this),\n-                    std::placeholders::_1), dependsOn);\n-    }\n-#endif\n-\n-    /**\n-      Construct an Output (wire) for the Component as function of the State.\n-      Specifiy a (member) function of the state implemented by this component to\n-      be an Output and include the Stage that output is dependent on. If no\n-      Stage is specified it defaults to Acceleration. Here\'s an example. Say you \n-      have a class Markers that manages markers, you have an instance of this class\n-      as a member variable in your Component, and Markers has a method\n-      <tt> Vec3 Markers::calcMarkerPos(const SimTK::State& s, std::string\n-      marker);</tt>\n-      to compute motion capture marker positions, given the name of a marker.\n-       @code\n-       constructOutput<SimTK::Vec3>("ankle_marker_pos",\n-               std::bind(&Markers::calcMarkerPos, _markers,\n-               std::placeholders::_1, "ankle"),\n-               SimTK::Stage::Position);\n-       @endcode\n-\n-      @see constructOutputForStateVariable()\n-    */\n-    template <typename T>\n-    void constructOutput(const std::string& name, \n-        const std::function<T(const SimTK::State&)> outputFunction, \n-        const SimTK::Stage& dependsOn = SimTK::Stage::Acceleration) {\n-        _outputsTable[name] = SimTK::ClonePtr<AbstractOutput>(new\n-                Output<T>(name, outputFunction, dependsOn));\n-    }\n-\n-    /** Construct an Output for a StateVariable. While this method is a\n-     * convenient way to construct an Output for a StateVariable, it is\n-     * inefficient because it uses a string lookup. To create a more efficient\n-     * Output, create a member variable that returns the state variable\n-     * directly; see the implementations of Coordinate::getValue() or\n-     * Muscle::getActivation() for examples.\n-     *\n-     * @param name Name of the output, which must be the same as the name of\n-     * the corresponding state variable.\n-     */\n-    void constructOutputForStateVariable(const std::string& name);\n-\n     /** Clear all designations of (sub)components for this Component. \n       * Components are not deleted- the list of references to its components is cleared. */\n     void clearComponents() {\n@@ -1603,6 +1528,95 @@ template <class T> friend class ComponentMeasure;\n \n     //@} \n \n+    /** @name Internal methods for constructing Outputs\n+     * To declare Outputs for your component, use the following macros within\n+     * your class declaration (ideally at the top near property declarations):\n+     *\n+     *  - #OpenSim_DECLARE_OUTPUT\n+     *  - #OpenSim_DECLARE_OUTPUT_FLEX\n+     *  - #OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE\n+     *\n+     * The methods below are used in those macros, and you should not use these\n+     * methods yourself.\n+     */\n+    /// @{\n+    /** Construct an output for a member function of the same component. \n+        The following must be true about componentMemberFunction, the function\n+        that returns the output:\n+\n+           -# It is a member function of \\a this Component.\n+           -# The member function is const.\n+           -# It takes only one input, which is `const SimTK::State&`\n+      \n+       If these are not true for your case, then use the more general method\n+       %Component::constructOutput(const std::string&,\n+                                  const std::function<T(const SimTK:State&)>,\n+                                  const SimTK::Stage&).\n+\n+       @see constructOutputForStateVariable()\n+     */\n+\n+#ifndef SWIG // SWIG can\'t parse the const at the end of the second argument.\n+    template <typename T, typename Class>\n+    bool constructOutput(const std::string& name,\n+            T(Class::*const componentMemberFunction)(const SimTK::State&) const,\n+            const SimTK::Stage& dependsOn = SimTK::Stage::Acceleration) {\n+        // The `const` in `Class::*const componentMemberFunction` means this\n+        // function can\'t assign componentMemberFunction to some other function\n+        // pointer. This is unlikely, since that function would have to match\n+        // the same template parameters (T and Class).\n+        return constructOutput<T>(name, std::bind(componentMemberFunction,\n+                    static_cast<Class*>(this),\n+                    std::placeholders::_1), dependsOn);\n+    }\n+#endif\n+\n+    /**\n+      Construct an Output (wire) for the Component as function of the State.\n+      Specifiy a (member) function of the state implemented by this component to\n+      be an Output and include the Stage that output is dependent on. If no\n+      Stage is specified it defaults to Acceleration. Here\'s an example. Say you \n+      have a class Markers that manages markers, you have an instance of this class\n+      as a member variable in your Component, and Markers has a method\n+      <tt> Vec3 Markers::calcMarkerPos(const SimTK::State& s, std::string\n+      marker);</tt>\n+      to compute motion capture marker positions, given the name of a marker.\n+       @code\n+       constructOutput<SimTK::Vec3>("ankle_marker_pos",\n+               std::bind(&Markers::calcMarkerPos, _markers,\n+               std::placeholders::_1, "ankle"),\n+               SimTK::Stage::Position);\n+       @endcode\n+\n+      @see constructOutputForStateVariable()\n+    */\n+    template <typename T>\n+    bool constructOutput(const std::string& name, \n+        const std::function<T(const SimTK::State&)> outputFunction, \n+        const SimTK::Stage& dependsOn = SimTK::Stage::Acceleration) {\n+        // TODO OPENSIM_THROW_IF(_outputsTable.count(name) == 1,\n+        // TODO         Exception, getConcreteClassName(), getName(),\n+        // TODO         "An output with name \'" + name + \n+        // TODO         "\' (type " + SimTK::NiceTypeName<T>::name() +\n+        // TODO         ") already exists.");\n+        _outputsTable[name] = SimTK::ClonePtr<AbstractOutput>(\n+                new Output<T>(name, outputFunction, dependsOn));\n+        return true;\n+    }\n+\n+    /** Construct an Output for a StateVariable. While this method is a\n+     * convenient way to construct an Output for a StateVariable, it is\n+     * inefficient because it uses a string lookup. To create a more efficient\n+     * Output, create a member variable that returns the state variable\n+     * directly; see the implementations of Coordinate::getValue() or\n+     * Muscle::getActivation() for examples.\n+     *\n+     * @param name Name of the output, which must be the same as the name of\n+     * the corresponding state variable. */\n+    bool constructOutputForStateVariable(const std::string& name);\n+    \n+    /// @}\n+\n private:\n     // Construct the table of serializeable properties for a Component.\n     // Base constructs property that contains the structural connectors.\ndiff --git a/OpenSim/Common/ComponentOutput.h b/OpenSim/Common/ComponentOutput.h\nindex c515c36ca..e4ef9a7ab 100644\n--- a/OpenSim/Common/ComponentOutput.h\n+++ b/OpenSim/Common/ComponentOutput.h\n@@ -144,7 +144,7 @@ public:\n     \n     /** determine the value type for this Output*/\n     std::string getTypeName() const override \n-        { return SimTK::NiceTypeName<T>::name(); }\n+        { return SimTK::NiceTypeName<T>::namestr(); }\n \n     std::string getValueAsString(const SimTK::State& state) const override\n     {\n@@ -164,6 +164,114 @@ private:\n //=============================================================================\n };  // END class Output\n \n+/// @name Creating Outputs for your Component\n+/// Use these macros at the top of your component class declaration,\n+/// near where you declare @ref Property properties.\n+/// @{\n+/** Create an output for a member function of this component.\n+ *  The following must be true about componentMemberFunction, the function\n+ *  that returns the output:\n+ *\n+ *     -# It is a member function of your component.\n+ *     -# The member function is const.\n+ *     -# It takes only one input, which is `const SimTK::State&`\n+ *\n+ *  Use #OpenSim_DECLARE_OUTPUT_FLEX if these are not true for you.\n+ *\n+ *  You must also provide the stage on which the output depends.\n+ *\n+ *  Here\'s an example for using this macro:\n+ *  @code{.cpp}\n+ *  class MyComponent : public Component {\n+ *  public:\n+ *      OpenSim_DECLARE_OUTPUT(force, double, getForce, SimTK::Stage::Dynamics);\n+ *      ...\n+ *  };\n+ *  @endcode\n+ * @see Component::constructOutput()\n+ * @relates OpenSim::Output\n+ */\n+#define OpenSim_DECLARE_OUTPUT(oname, T, func, ostage)                      \\\n+    /** @name Outputs                                                    */ \\\n+    /** @{                                                               */ \\\n+    /** Provides the value of func##() and is available at stage ostage. */ \\\n+    /** This output was generated with the                               */ \\\n+    /** #OpenSim_DECLARE_OUTPUT macro.                                   */ \\\n+    OpenSim_DOXYGEN_Q_PROPERTY(T, oname)                                    \\\n+    /** @}                                                               */ \\\n+    /** @cond                                                            */ \\\n+    bool _has_output_##oname { constructOutput<T>(#oname, &Self::func, ostage) }; \\\n+    /** @endcond                                                         */\n+\n+// Note: we could omit the T argument from the above macro by using the\n+// following code to deduce T from the provided func\n+//      std::result_of<decltype(&Self::func)(Self, const SimTK::State&)>::type\n+// However, then we wouldn\'t be able to document the type for the output in\n+// doxygen.\n+\n+/** The most flexible (and difficult) way to create an output.\n+   You can specify any function that has the signature `func_name(const\n+   SimTK::State&)`.  You must also provide the stage on which the output\n+   depends, and a comment describing the output.\n+  \n+   Here\'s an example. Say you have a class Markers that manages markers, you\n+   have an instance of this class as a member variable in your Component, and\n+   Markers has a method <tt> Vec3 Markers::calcMarkerPos(const SimTK::State& s,\n+   std::string marker);</tt> to compute motion capture marker positions, given\n+   the name of a marker.\n+   @code{.cpp}\n+   OpenSim_DECLARE_OUTPUT_FLEX(ankle_marker_pos,\n+           std::bind(&Markers::calcMarkerPos, _markers,  std::placeholders::_1, "ankle"),\n+           SimTK::Stage::Position);\n+   @endcode\n+   @see Component::constructOutput()\n+   @relates OpenSim::Output\n+ */\n+#define OpenSim_DECLARE_OUTPUT_FLEX(oname, T, func, ostage, comment)        \\\n+    /** @name Outputs                                                    */ \\\n+    /** @{                                                               */ \\\n+    /** comment                                                          */ \\\n+    /** Available at stage ostage.                                       */ \\\n+    /** This output was generated with the                               */ \\\n+    /** #OpenSim_DECLARE_OUTPUT_FLEX macro.                              */ \\\n+    OpenSim_DOXYGEN_Q_PROPERTY(T, oname)                                    \\\n+    /** @}                                                               */ \\\n+    /** @cond                                                            */ \\\n+    bool _has_output_##oname { constructOutput<T>(#oname, func, ostage) }; \\\n+    /** @endcond                                                         */\n+\n+/** Create an Output for a StateVariable in this component. The provided\n+ * name is both the name of the output and of the state variable.\n+ *\n+ * While this macro is a convenient way to construct an Output for a\n+ * StateVariable, it is inefficient because it uses a string lookup at runtime.\n+ * To create a more efficient Output, create a member variable that returns the\n+ * state variable directly (see Coordinate::getValue() or\n+ * Muscle::getActivation()) and then use the #OpenSim_DECLARE_OUTPUT macro.\n+ *\n+ * @code{.cpp}\n+ * class MyComponent : public Component {\n+ * public:\n+ *     OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE(activation);\n+ *     ...\n+ * };\n+ * @endcode\n+ * @see Component::constructOutputForStateVariable()\n+ * @relates OpenSim::Output\n+ */\n+#define OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE(oname)                    \\\n+    /** @name Outputs                                                    */ \\\n+    /** @{                                                               */ \\\n+    /** Provides the value of this class\'s oname state variable.         */ \\\n+    /** Available at stage SimTK::Stage::Model.                          */ \\\n+    /** This output was generated with the                               */ \\\n+    /** #OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE macro.                */ \\\n+    OpenSim_DOXYGEN_Q_PROPERTY(T, oname)                                    \\\n+    /** @}                                                               */ \\\n+    /** @cond                                                            */ \\\n+    bool _has_output_##oname { constructOutputForStateVariable(#oname) }; \\\n+    /** @endcond                                                         */\n+/// @}\n //=============================================================================\n //=============================================================================\n \ndiff --git a/OpenSim/Common/DataTable.h b/OpenSim/Common/DataTable.h\nindex da1711401..ec3b45f5d 100644\n--- a/OpenSim/Common/DataTable.h\n+++ b/OpenSim/Common/DataTable.h\n@@ -154,7 +154,7 @@ public:\n     size_t getNumColumns() const {\n         return implementGetNumColumns();\n     }\n-    \n+\n     /** Get metadata associated with the independent column.                  */\n     const IndependentMetaData& getIndependentMetaData() const {\n         return _independentMetaData;\n@@ -171,7 +171,7 @@ public:\n     const DependentsMetaData& getDependentsMetaData() const {\n         return _dependentsMetaData;\n     }\n-    \n+\n     /** Set metadata associated with the dependent columns.                   */\n     void \n     setDependentsMetaData(const DependentsMetaData& dependentsMetaData) {\n@@ -179,6 +179,39 @@ public:\n         validateDependentsMetaData();\n     }\n \n+    /** Get column labels.                                                    */\n+    std::vector<std::string> getColumnLabels() const {\n+        const auto& metadata = getDependentsMetaData();\n+        const auto& absArray = metadata.getValueArrayForKey("labels");\n+        std::vector<std::string> labels{};\n+        for(size_t i = 0; i < absArray.size(); ++i)\n+            labels.push_back(absArray[i].getValue<std::string>());\n+\n+        return labels;\n+    }\n+\n+    /** Set column labels.                                                    */\n+    void setColumnLabels(const std::vector<std::string>& columnLabels) {\n+        ValueArray<std::string> newLabels{};\n+        for(const auto& label : columnLabels)\n+            newLabels.upd().push_back(SimTK::Value<std::string>(label));\n+        _dependentsMetaData.removeValueArrayForKey("labels");\n+        _dependentsMetaData.setValueArrayForKey("labels", newLabels);\n+\n+        validateDependentsMetaData();\n+    }\n+\n+    /** Get index of a column label.                                          */\n+    size_t getColumnIndex(const std::string& columnLabel) const {\n+        const auto& metadata = getDependentsMetaData();\n+        const auto& absArray = metadata.getValueArrayForKey("labels");\n+        for(size_t i = 0; i < absArray.size(); ++i)\n+            if(absArray[i].getValue<std::string>() == columnLabel)\n+                return i;\n+        \n+        OPENSIM_THROW(KeyNotFound, columnLabel);\n+    }\n+    \n protected:\n     /** Get number of rows. Implemented by derived classes.                   */\n     virtual size_t implementGetNumRows() const       = 0;\n@@ -312,6 +345,11 @@ public:\n         return _depData.col((int)index);\n     }\n \n+    /** Get dependent Column which has the given column label.                */\n+    VectorView getDependentColumn(const std::string& columnLabel) {\n+        return _depData.col(getColumnIndex(columnLabel));\n+    }\n+\n     /** Set independent column at index.                                      \n \n     \\throws RowIndexOutOfRange If index is out of range.                        \ndiff --git a/OpenSim/Common/Exception.cpp b/OpenSim/Common/Exception.cpp\nindex ea056a3b2..678e35851 100644\n--- a/OpenSim/Common/Exception.cpp\n+++ b/OpenSim/Common/Exception.cpp\n@@ -74,6 +74,14 @@ Exception::Exception(const std::string& file,\n                func + "\'");\n }\n \n+Exception::Exception(const std::string& file,\n+                     size_t line,\n+                     const std::string& func,\n+                     const std::string& msg)\n+        : Exception(file, line, func) {\n+    addMessage(msg);\n+}\n+\n void\n Exception::addMessage(const std::string& msg) {\n     if(_msg.length() == 0)\ndiff --git a/OpenSim/Common/Exception.h b/OpenSim/Common/Exception.h\nindex cd66a38e3..c4df3afb4 100644\n--- a/OpenSim/Common/Exception.h\n+++ b/OpenSim/Common/Exception.h\n@@ -137,11 +137,18 @@ public:\n               int aLine=-1);\n \n     /** Call this constructor from derived classes to add file, line and \n-    function information to the error message                                 */\n+    function information to the error message.                                */\n     Exception(const std::string& file,\n               size_t line,\n               const std::string& func);\n \n+    /** Use this when you want to throw an Exception (with OPENSIM_THROW or\n+    OPENSIM_THROW_IF) and also provide a message.                             */\n+    Exception(const std::string& file,\n+              size_t line,\n+              const std::string& func,\n+              const std::string& msg);\n+\n     virtual ~Exception() throw() {}\n \n protected:\ndiff --git a/OpenSim/Common/Property.h b/OpenSim/Common/Property.h\nindex f19884a75..bce1feee5 100644\n--- a/OpenSim/Common/Property.h\n+++ b/OpenSim/Common/Property.h\n@@ -1160,6 +1160,7 @@ SimTK_DEFINE_UNIQUE_INDEX_TYPE(PropertyIndex);\n // don\'t want to prevent our users from potentially using OpenSim in\n // conjunction with Qt.  You can see how this empty macro is used in some of\n // the macros below.\n+// We actually also use this macro to document component outputs, etc.\n #define OpenSim_DOXYGEN_Q_PROPERTY(T, name)\n \n /** Declare a required, single-value property of the given \\a pname and \n@@ -1188,6 +1189,8 @@ A data member is also created but is intended for internal use only:\n             this->template addProperty<T>(#pname,comment,initValue);        \\\n     }                                                                       \\\n     /** @endcond **/                                                        \\\n+    /** @name Properties (single-value)                                  */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1197,6 +1200,7 @@ A data member is also created but is intended for internal use only:\n     /** @propmethods get_##pname##(), upd_##pname##(), set_##pname##()   */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     /** Get the value of the <b> pname </b> property.                    */ \\\n@@ -1222,6 +1226,8 @@ initialized with an object of type T.\n     {   PropertyIndex_##T =                                                 \\\n             this->template addProperty<T>("", comment, initValue); }        \\\n     /** @endcond **/                                                        \\\n+    /** @name Properties (unnamed)                                       */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<%##T##\\></b>.                                       */ \\\n@@ -1231,6 +1237,7 @@ initialized with an object of type T.\n     /** @propmethods get_##T##(), upd_##T##(), set_##T##()               */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, T)                                        \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     /** Get the value of the <b> %##T </b> property.                     */ \\\n@@ -1260,6 +1267,8 @@ value of type T.\n             this->template addOptionalProperty<T>(#pname, comment,          \\\n                                                   initValue); }             \\\n     /** @endcond **/                                                        \\\n+    /** @name Properties (optional)                                      */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1269,6 +1278,7 @@ value of type T.\n     /** @propmethods get_##pname##(), upd_##pname##(), set_##pname##()   */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     /** Get the value of the <b> pname </b> property.                    */ \\\n@@ -1292,6 +1302,8 @@ supports a %size() method and operator[] element selection.\n @see OpenSim_DECLARE_LIST_PROPERTY_RANGE()\n @relates OpenSim::Property **/\n #define OpenSim_DECLARE_LIST_PROPERTY(pname, T, comment)                    \\\n+    /** @name Properties (list)                                          */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1302,6 +1314,7 @@ supports a %size() method and operator[] element selection.\n     /**     append_##pname##()                                           */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     OpenSim_DECLARE_LIST_PROPERTY_HELPER(pname, T, comment,                 \\\n@@ -1321,6 +1334,8 @@ the right number of elements, using any Container that supports a %size()\n method and operator[] element selection.\n @relates OpenSim::Property **/\n #define OpenSim_DECLARE_LIST_PROPERTY_SIZE(pname, T, listSize, comment)     \\\n+    /** @name Properties (list)                                          */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1331,6 +1346,7 @@ method and operator[] element selection.\n     /** @propmethods get_##pname##(), upd_##pname##(), set_##pname##()   */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     OpenSim_DECLARE_LIST_PROPERTY_HELPER(pname, T, comment,                 \\\n@@ -1345,6 +1361,8 @@ using any Container that supports a %size() method and operator[] element\n selection.\n @relates OpenSim::Property **/\n #define OpenSim_DECLARE_LIST_PROPERTY_ATLEAST(pname, T, minSize, comment)   \\\n+    /** @name Properties (list)                                          */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1356,6 +1374,7 @@ selection.\n     /**     append_##pname##()                                           */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     OpenSim_DECLARE_LIST_PROPERTY_HELPER(pname, T, comment,                 \\\n@@ -1370,6 +1389,8 @@ no more than \\a maxSize elements, using any Container that supports a %size()\n method and operator[] element selection.\n @relates OpenSim::Property **/\n #define OpenSim_DECLARE_LIST_PROPERTY_ATMOST(pname, T, maxSize, comment)    \\\n+    /** @name Properties (list)                                          */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1381,6 +1402,7 @@ method and operator[] element selection.\n     /**     append_##pname##()                                           */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     OpenSim_DECLARE_LIST_PROPERTY_HELPER(pname, T, comment, 0, (maxSize))   \\\n@@ -1400,6 +1422,8 @@ OpenSim_DECLARE_PROPERTY_ATMOST() rather than this macro.\n @relates OpenSim::Property **/\n #define OpenSim_DECLARE_LIST_PROPERTY_RANGE(pname, T, minSize, maxSize,     \\\n                                             comment)                        \\\n+    /** @name Properties (list)                                          */ \\\n+    /** @{                                                               */ \\\n     /** comment                                                          */ \\\n     /** This property appears in XML files under                         */ \\\n     /** the tag <b>\\<##pname##\\></b>.                                    */ \\\n@@ -1412,6 +1436,7 @@ OpenSim_DECLARE_PROPERTY_ATMOST() rather than this macro.\n     /**     append_##pname##()                                           */ \\\n     /* This macro below is explained above.                              */ \\\n     OpenSim_DOXYGEN_Q_PROPERTY(T, pname)                                    \\\n+    /** @}                                                               */ \\\n     /** @name Property-related methods                                   */ \\\n     /** @{                                                               */ \\\n     OpenSim_DECLARE_LIST_PROPERTY_HELPER(pname, T, comment,                 \\\ndiff --git a/OpenSim/Common/Storage.cpp b/OpenSim/Common/Storage.cpp\nindex 234539004..684ad51a0 100644\n--- a/OpenSim/Common/Storage.cpp\n+++ b/OpenSim/Common/Storage.cpp\n@@ -414,61 +414,66 @@ getHeaderToken() const\n // COLUMN LABELS\n //-----------------------------------------------------------------------------\n //_____________________________________________________________________________\n-/**\n- * Get the column index corresponding to specified column name.\n- *\n- * @return State index of column or -1.  Note that the returned index is equivalent\n- * to the state index.  For example, for the first column in a storage (usually\n- * time) -1 would be returned.  For the second column in a storage (the first\n- * state) 0 would be returned.\n- * @todo Rename this method getStateIndex()\n- * \n- * added a default Parameter for startIndex. -Ayman\n- */\n+// added a default Parameter for startIndex. -Ayman\n+// TODO startIndex is being ignored.\n const int Storage::\n getStateIndex(const std::string &aColumnName, int startIndex) const\n {\n-    int thisColumnIndex = _columnLabels.findIndex(aColumnName);\n-    if (thisColumnIndex >= 0)\n-        // subtract 1 because time is included in the labels but not \n-        // in the "state vector"\n-        return thisColumnIndex-1;\n-\n-    // Assume a mismatch between earlier and the latest component state variable \n-    // labeling mechanism and redo find with the just the ending substring instead\n-    // of its full path name\n-    std::string::size_type back = aColumnName.rfind("/");\n-    std::string prefix = aColumnName.substr(0, back);\n-    std::string shortName = aColumnName.substr(back + 1, aColumnName.length() - back);\n-    thisColumnIndex = _columnLabels.findIndex(shortName);\n-\n-    // additional checking for old coordinate state names that have been renamed\n-    // <coord_name>/value and <coord_name>/speed\n-    if (thisColumnIndex < 0){\n-        if (shortName == "value"){\n-            // old formats did not have "/value" so remove it if here\n+    int thisColumnIndex = -1;\n+\n+    // This uses the `do while(false)` idiom to run common code if one of a\n+    // number of conditions succeeds (much like what a goto would be used for).\n+    do {\n+        thisColumnIndex = _columnLabels.findIndex(aColumnName);\n+        if (thisColumnIndex != -1) break;\n+\n+        // Assume column labels follow pre-v4.0 state variable labeling.\n+        // Redo search with what the pre-v4.0 label might have been.\n+\n+        // First, try just the last element of the path.\n+        std::string::size_type back = aColumnName.rfind("/");\n+        std::string prefix = aColumnName.substr(0, back);\n+        std::string shortName = aColumnName.substr(back + 1,\n+                                                   aColumnName.length() - back);\n+        thisColumnIndex = _columnLabels.findIndex(shortName);\n+        if (thisColumnIndex != -1) break;\n+\n+        // If that didn\'t work, specifically check for coordinate state names\n+        // (<coord_name>/value and <coord_name>/speed) and muscle state names\n+        // (<muscle_name>/activation <muscle_name>/fiber_length).\n+        if (shortName == "value") {\n+            // pre-v4.0 did not have "/value" so remove it if here\n             back = prefix.rfind("/");\n             shortName = prefix.substr(back + 1, prefix.length());\n             thisColumnIndex = _columnLabels.findIndex(shortName);\n         }\n-        else if (shortName == "speed"){\n-            // replace "/speed" (the latest labeling for speeds) with "_u"\n+        else if (shortName == "speed") {\n+            // replace "/speed" (the v4.0 labeling for speeds) with "_u"\n             back = prefix.rfind("/");\n-            shortName = prefix.substr(back + 1, prefix.length() - back) + "_u";\n+            shortName =\n+                    prefix.substr(back + 1, prefix.length() - back) + "_u";\n             thisColumnIndex = _columnLabels.findIndex(shortName);\n         }\n         else if (back < aColumnName.length()) {\n-            // try replacing the \'/\' with \'.\' in the last connection\n+            // try replacing the \'/\' with \'.\' in the last segment\n             shortName = aColumnName;\n             shortName.replace(back, 1, ".");\n             back = shortName.rfind("/");\n-            shortName = shortName.substr(back + 1, shortName.length() - back);\n+            shortName = shortName.substr(back + 1,\n+                                         shortName.length() - back);\n             thisColumnIndex = _columnLabels.findIndex(shortName);\n         }\n-    }\n-    // subtract 1 because time is included in the labels but not \n-    // in the "state vector"\n-    return thisColumnIndex-1;\n+        if (thisColumnIndex != -1) break;\n+\n+        // If all of the above checks failed, return -1.\n+        return -1;\n+\n+    } while (false);\n+\n+    // If we get here, we successfully found a column.\n+    // Subtract 1 because time is included in the labels but not\n+    // in the "state vector".\n+    return thisColumnIndex - 1;\n }\n \n \n@@ -3314,34 +3319,39 @@ void Storage::compareWithStandard(Storage& standard, Array<string> &columnsUsed,\n     columnsUsed.setSize(columns);\n     comparisons.setSize(columns);\n }\n-/**\n- * Force column labels for a Storage object to become unique. This is done by prepending the string (n_)\n- * as needed where n=1, 2, ...\n- *\n- * @returns true if labels were changed false otherwise.\n- **/\n+\n bool Storage::makeStorageLabelsUnique() {\n     Array<std::string> lbls = getColumnLabels();\n-    std::string offending="";\n-    bool changedLabels=false;\n-    for(int i=0; i< lbls.getSize(); i++){\n-        bool isUnique= (lbls.findIndex(lbls[i])==i);\n-        if (!isUnique){ // Make new names\n-            offending =lbls[i];\n-            bool exist=true;\n-            std::string newName =offending;\n+    std::string offending = "";\n+    bool changedLabels = false;\n+    for(int i = 0; i < lbls.getSize(); i++){\n+        bool isUnique = (lbls.findIndex(lbls[i]) == i);\n+        if (!isUnique) { // Make new names\n+            offending = lbls[i];\n+            bool exist = true;\n+            std::string newName = offending;\n             changedLabels = true;\n-            int c=1;\n-            while(exist){\n+            int c = 1;\n+            while (exist) {\n                 char cString[20];\n                 sprintf(cString,"%d", c);\n-                newName = std::string(cString)+"_"+offending;\n-                exist= (lbls.findIndex(newName)!=-1);\n+                newName = std::string(cString) + "_" + offending;\n+                exist = (lbls.findIndex(newName) != -1);\n                 c++;\n             }\n-            lbls[i]= newName;\n+            lbls[i] = newName;\n         }\n     }\n     if (changedLabels) setColumnLabels(lbls);\n-    return (!changedLabels);\n+    const bool labelsWereUnique = (!changedLabels);\n+    return labelsWereUnique;\n+}\n+\n+bool Storage::storageLabelsAreUnique() const {\n+    const auto& lbls = getColumnLabels();\n+    for(int i = 0; i < lbls.getSize(); i++) {\n+        const bool isUnique = (lbls.findIndex(lbls[i]) == i);\n+        if (!isUnique) return false;\n+    }\n+    return true;\n }\ndiff --git a/OpenSim/Common/Storage.h b/OpenSim/Common/Storage.h\nindex a73304f16..33698fe81 100644\n--- a/OpenSim/Common/Storage.h\n+++ b/OpenSim/Common/Storage.h\n@@ -218,9 +218,19 @@ public:\n     void setHeaderToken(const std::string &aToken);\n     const std::string& getHeaderToken() const;\n     // COLUMN LABELS\n+    /** Get the column index corresponding to specified column name. This\n+     * function attempts to handle the change in state variable names that\n+     * occurred in OpenSim version 4.0; for example, if you search for\n+     * `<coord-name>/speed` and it is not found, then this function looks for\n+     * `<coord-name>_u`.\n+     *\n+     * @return State index of column or -1.  Note that the returned index is\n+     * equivalent to the state index.  For example, for the first column in a\n+     * storage (usually time) -1 would be returned.  For the second column in a\n+     * storage (the first state) 0 would be returned. */\n     const int getStateIndex(const std::string &aColumnName, int startIndex=0) const;\n-    void setColumnLabels(const Array<std::string> &aColumnLabels);\n-    const Array<std::string> &getColumnLabels() const;\n+    void setColumnLabels(const Array<std::string>& aColumnLabels);\n+    const Array<std::string>& getColumnLabels() const;\n     //--------------------------------------------------------------------------\n     // RESET\n     //--------------------------------------------------------------------------\n@@ -292,7 +302,13 @@ public:\n                          double startTime=SimTK::NaN, double endTime=SimTK::NaN);\n     //void checkAgainstStandard(Storage standard, Array<double> &tolerances, std::string testFile = "", int testFileLine = -1, std::string errorMessage = "Exception");\n     void compareWithStandard(Storage& standard, Array<std::string> &columnsUsed, Array<double> &comparisons);\n+    /** Force column labels for a Storage object to become unique. This is done\n+     * by prepending the string (n_) as needed where n=1, 2, ...\n+     *\n+     * @returns true if labels were already unique.\n+     **/\n     bool makeStorageLabelsUnique();\n+    bool storageLabelsAreUnique() const;\n     //--------------------------------------------------------------------------\n     // IO\n     //--------------------------------------------------------------------------\ndiff --git a/OpenSim/Common/Test/testComponentInterface.cpp b/OpenSim/Common/Test/testComponentInterface.cpp\nindex 9817fa8ca..e678fc99f 100644\n--- a/OpenSim/Common/Test/testComponentInterface.cpp\n+++ b/OpenSim/Common/Test/testComponentInterface.cpp\n@@ -130,6 +130,19 @@ public:\n     OpenSim_DECLARE_LIST_PROPERTY_SIZE(inertia, double, 6,\n         "inertia {Ixx, Iyy, Izz, Ixy, Ixz, Iyz}");\n \n+    OpenSim_DECLARE_OUTPUT(Output1, double, getSomething, SimTK::Stage::Time)\n+    OpenSim_DECLARE_OUTPUT(Output2, SimTK::Vec3, calcSomething,\n+            SimTK::Stage::Time)\n+\n+    OpenSim_DECLARE_OUTPUT_FLEX(Qs, Vector,\n+            std::bind([=](const SimTK::State& s)->Vector{return s.getQ(); },\n+                std::placeholders::_1),\n+            SimTK::Stage::Position, "")\n+\n+    OpenSim_DECLARE_OUTPUT_FLEX(BodyAcc, SpatialVec,\n+            std::bind(&Foo::calcSpatialAcc, this, std::placeholders::_1),\n+            SimTK::Stage::Velocity, "")\n+\n     Foo() : Component() {\n         constructInfrastructure();\n         m_ctr = 0;\n@@ -193,6 +206,7 @@ private:\n     int m_ctr;\n     mutable int m_mutableCtr;\n \n+\n     void constructProperties() override {\n         constructProperty_mass(1.0);\n         Array<double> inertia(0.001, 6);\n@@ -209,20 +223,8 @@ private:\n     }\n \n     void constructOutputs() override {\n-        constructOutput<double>("Output1", &Foo::getSomething,\n-                SimTK::Stage::Time);\n-\n-        constructOutput<SimTK::Vec3>("Output2", &Foo::calcSomething,\n-                SimTK::Stage::Time);\n \n-        double a = 10;\n-        constructOutput<Vector>("Qs",\n-            std::bind([=](const SimTK::State& s)->Vector{return s.getQ(); }, std::placeholders::_1),\n-            SimTK::Stage::Position);\n \n-        constructOutput<SpatialVec>("BodyAcc",\n-            std::bind(&Foo::calcSpatialAcc, this, std::placeholders::_1),\n-            SimTK::Stage::Velocity);\n     }\n \n     // Keep indices and reference to the world\n@@ -234,6 +236,14 @@ private:\n class Bar : public Component {\n     OpenSim_DECLARE_CONCRETE_OBJECT(Bar, Component);\n public:\n+\n+    OpenSim_DECLARE_OUTPUT_FLEX(PotentialEnergy, double,\n+        std::bind(&Bar::getPotentialEnergy, this, std::placeholders::_1),\n+        SimTK::Stage::Velocity, "")\n+\n+    OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE(fiberLength);\n+    OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE(activation);\n+\n     Bar() : Component() { constructInfrastructure(); }\n \n     double getPotentialEnergy(const SimTK::State& state) const {\n@@ -297,19 +307,11 @@ protected:\n     }\n \n private:\n-    void constructConnectors() override{\n+    void constructConnectors() override {\n         constructConnector<Foo>("parentFoo");\n         constructConnector<Foo>("childFoo");\n     }\n \n-    void constructOutputs() override {\n-        constructOutput<double>("PotentialEnergy",\n-        std::bind(&Bar::getPotentialEnergy, this, std::placeholders::_1),\n-        SimTK::Stage::Velocity);\n-        constructOutputForStateVariable("fiberLength");\n-        constructOutputForStateVariable("activation");\n-    }\n-\n     // keep track of the force added by the component\n     mutable ForceIndex fix;\n     ReferencePtr<TheWorld> world;\ndiff --git a/OpenSim/Common/Test/testDataTable.cpp b/OpenSim/Common/Test/testDataTable.cpp\nindex a4d483398..bc0eb0182 100644\n--- a/OpenSim/Common/Test/testDataTable.cpp\n+++ b/OpenSim/Common/Test/testDataTable.cpp\n@@ -47,6 +47,19 @@ int main() {\n     ind_metadata.setValueForKey("column-index", unsigned{0});\n \n     TimeSeriesTable table{};\n+    {\n+        table.setColumnLabels({"0", "1", "2", "3"});\n+        const auto& labels = table.getColumnLabels();\n+        for(size_t i = 0; i < labels.size(); ++i) \n+            if(labels.at(i) != std::to_string(i))\n+                throw Exception{"Test failed: labels.at(i) != "\n+                                "std::to_string(i)"};\n+\n+        for(size_t i = 0; i < labels.size(); ++i)\n+            if(table.getColumnIndex(labels.at(i)) != i)\n+                throw Exception{"Test failed: "\n+                                "table.getColumnIndex(labels.at(i)) != i"};\n+    }\n     table.setDependentsMetaData(dep_metadata);\n     table.setIndependentMetaData(ind_metadata);\n \n@@ -83,6 +96,13 @@ int main() {\n         if(labels_ref[i].getValue<std::string>() != std::to_string(i + 1))\n             throw Exception{"Test failed: labels_ref[i].getValue<std::string>()"\n                     " != std::to_string(i + 1)"};\n+    {\n+    const auto& labels = table.getColumnLabels();\n+    for(unsigned i = 0; i < 5; ++i)\n+        if(labels.at(i) != std::to_string(i + 1))\n+            throw Exception{"Test failed: labels[i].getValue<std::string>()"\n+                    " != std::to_string(i + 1)"};\n+    }\n \n     const auto& col_index_ref \n         = dep_metadata_ref.getValueArrayForKey("column-index");\ndiff --git a/OpenSim/Common/XMLDocument.cpp b/OpenSim/Common/XMLDocument.cpp\nindex f6ecf22c6..635edf615 100644\n--- a/OpenSim/Common/XMLDocument.cpp\n+++ b/OpenSim/Common/XMLDocument.cpp\n@@ -460,4 +460,4 @@ void XMLDocument::addPhysicalOffsetFrame(SimTK::Xml::Element& element,\n \n     frames_node->insertNodeAfter(frames_node->element_end(), newFrameElement);\n     //frames_node->writeToString(debug);\n-}\n\\ No newline at end of file\n+}\ndiff --git a/OpenSim/Examples/DataTable/CMakeLists.txt b/OpenSim/Examples/DataTable/CMakeLists.txt\nindex b516b28ca..f9d603d71 100644\n--- a/OpenSim/Examples/DataTable/CMakeLists.txt\n+++ b/OpenSim/Examples/DataTable/CMakeLists.txt\n@@ -1,7 +1,12 @@\n-include_directories(${PROJECT_SOURCE_DIR})\n+set(EXAMPLES_TO_COMPILE example1.cpp\n+                        example2.cpp\n+)\n \n-add_executable(example1DataTable example1.cpp)\n-target_link_libraries(example1DataTable ${Simbody_LIBRARIES} osimCommon)\n+include_directories(${OpenSim_SOURCE_DIR} ${OpenSim_SOURCE_DIR}/Vendors)\n \n-add_executable(example2DataTable example2.cpp)\n-target_link_libraries(example2DataTable ${Simbody_LIBRARIES} osimCommon)\n+foreach(EXAMPLE_PROG ${EXAMPLES_TO_COMPILE})\n+    get_filename_component(EXAMPLE_ROOT ${EXAMPLE_PROG} NAME_WE)\n+    add_executable(${EXAMPLE_ROOT}DataTable ${EXAMPLE_PROG})\n+    target_link_libraries(${EXAMPLE_ROOT}DataTable ${Simbody_LIBRARIES} osimCommon)\n+    set_target_properties(${EXAMPLE_ROOT}DataTable PROPERTIES FOLDER "Examples")\n+endforeach(EXAMPLE_PROG ${EXAMPLES_TO_COMPILE})\ndiff --git a/OpenSim/Examples/DataTable/example1.cpp b/OpenSim/Examples/DataTable/example1.cpp\nindex fa435c676..1537f18a8 100644\n--- a/OpenSim/Examples/DataTable/example1.cpp\n+++ b/OpenSim/Examples/DataTable/example1.cpp\n@@ -23,20 +23,18 @@\n \n #include "OpenSim/Common/TimeSeriesTable.h"\n \n+#include <vector>\n+\n+\n int main() {\n     using namespace OpenSim;\n \n     DataTable table{};\n \n-    ValueArray<std::string> value_array{};\n-    auto& vec = value_array.upd();\n-    for(unsigned i = 0; i < 5; ++i)\n-        vec.push_back(SimTK::Value<std::string>{std::to_string(i)});\n+    // Add column labels to the table. \n+    table.setColumnLabels({"0", "1", "2", "3", "4"});\n \n-    DataTable::DependentsMetaData dep_metadata{};\n-    dep_metadata.setValueArrayForKey("labels", value_array);\n-\n-    table.setDependentsMetaData(dep_metadata);\n+    // Append rows to the table.\n \n     SimTK::RowVector_<double> row0{5, double{0}};\n     \n@@ -58,5 +56,8 @@ int main() {\n \n     table.appendRow(1.00, row4);\n \n+    // Retrieve a column by its label.\n+    table.getDependentColumn("3");\n+\n     return 0;\n }\ndiff --git a/OpenSim/Examples/DataTable/example2.cpp b/OpenSim/Examples/DataTable/example2.cpp\nindex 09ad0bd3e..1e9cd5478 100644\n--- a/OpenSim/Examples/DataTable/example2.cpp\n+++ b/OpenSim/Examples/DataTable/example2.cpp\n@@ -28,58 +28,53 @@\n int main() {\n     using namespace OpenSim;\n \n-    DataTable data_table{};\n+    DataTable dataTable{};\n \n-    ValueArray<std::string> labelValues{};\n-    auto& vec = labelValues.upd();\n-    for(unsigned i = 0; i < 5; ++i)\n-        vec.push_back(SimTK::Value<std::string>{std::to_string(i)});\n+    // Add column labels to the table. \n+    dataTable.setColumnLabels({"0", "1", "2", "3", "4"});\n \n-    TimeSeriesTable::DependentsMetaData dep_metadata{};\n-    dep_metadata.setValueArrayForKey("labels", labelValues);\n-\n-    data_table.setDependentsMetaData(dep_metadata);\n+    // Append rows to the table.\n \n     SimTK::RowVector_<double> row0{5, double{0}};\n     \n-    data_table.appendRow(0.00, row0);\n+    dataTable.appendRow(0.00, row0);\n \n     auto row1 = row0 + 1;\n \n-    data_table.appendRow(0.25, row1);\n+    dataTable.appendRow(0.25, row1);\n \n     auto row2 = row1 + 1;\n \n-    data_table.appendRow(0.50, row2);\n+    dataTable.appendRow(0.50, row2);\n \n     auto row3 = row2 + 1;\n \n-    data_table.appendRow(0.75, row3);\n+    dataTable.appendRow(0.75, row3);\n     \n     auto row4 = row3 + 1;\n \n-    data_table.appendRow(1.00, row4);\n+    dataTable.appendRow(1.00, row4);\n \n     // Following construction of TimeSeriesTable succeeds because the DataTable\n     // has its independent column strictly increasing.\n-    TimeSeriesTable timeseries_table1{data_table};\n+    TimeSeriesTable timeseries_table1{dataTable};\n \n     // Editing the DataTable to not have strictly increasing independent column\n     // will fail the construction of TimeSeriesTable.\n     auto row5 = row4 + 1;\n     \n-    data_table.appendRow(0.9, row5); // 0.9 is less than previous value (1.00).\n+    dataTable.appendRow(0.9, row5); // 0.9 is less than previous value (1.00).\n \n     // Contruction of TimeSeriesTable fails because independent column is not\n     // strictly increasing. \n     ASSERT_THROW(OpenSim::Exception,\n-                 TimeSeriesTable timeseries_table2{data_table});\n+                 TimeSeriesTable timeseries_table2{dataTable});\n \n     // Edit the entry in the independent column to make the column strictly\n     // increasing.\n-    data_table.setIndependentColumnAtIndex(5, 1.25);\n+    dataTable.setIndependentColumnAtIndex(5, 1.25);\n     // TimeSeriesTable construction now successful. \n-    TimeSeriesTable timeseries_table3{data_table};\n+    TimeSeriesTable timeseries_table3{dataTable};\n \n     return 0;\n }\ndiff --git a/OpenSim/OpenSimDoxygenMain.h b/OpenSim/OpenSimDoxygenMain.h\nindex 1ccc3a22c..e7a865f4d 100644\n--- a/OpenSim/OpenSimDoxygenMain.h\n+++ b/OpenSim/OpenSimDoxygenMain.h\n@@ -211,6 +211,7 @@ model components, such as body, constraint, or joint.\n - OpenSim::Function\n - OpenSim::Joint\n - OpenSim::Muscle\n+- OpenSim::StatesTrajectory\n \n <b>Classes of interest in Simbody:</b>\n \ndiff --git a/OpenSim/Sandbox/CMakeLists.txt b/OpenSim/Sandbox/CMakeLists.txt\nindex 9ce4a1ffe..9586e9320 100644\n--- a/OpenSim/Sandbox/CMakeLists.txt\n+++ b/OpenSim/Sandbox/CMakeLists.txt\n@@ -17,6 +17,8 @@ foreach(dataFile ${SANDBOX_FILES})\n     configure_file(${dataFile} ${CMAKE_CURRENT_BINARY_DIR}/${dataFile} COPYONLY)\n endforeach()\n \n+OpenSimCopySharedTestFiles(gait10dof18musc_subject01.osim)\n+\n foreach(exec_file ${TO_COMPILE})\n     get_filename_component(_target_name ${exec_file} NAME_WE)\n     add_executable(${_target_name} EXCLUDE_FROM_ALL ${exec_file})\ndiff --git a/OpenSim/Sandbox/futureMuscleMetabolicsResponse.cpp b/OpenSim/Sandbox/futureMuscleMetabolicsResponse.cpp\nindex 584d97ac4..330e056bf 100644\n--- a/OpenSim/Sandbox/futureMuscleMetabolicsResponse.cpp\n+++ b/OpenSim/Sandbox/futureMuscleMetabolicsResponse.cpp\n@@ -7,6 +7,11 @@ class ComplexResponse : public ModelComponent {\n     OpenSim_DECLARE_CONCRETE_OBJECT(ComplexResponse, ModelComponent);\n public:\n     OpenSim_DECLARE_PROPERTY(strength, double, "per-coord param.");\n+\n+    OpenSim_DECLARE_OUTPUT(term_1, double, getTerm1, SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(term_2, double, getTerm2, SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(sum, double, getTotal, SimTK::Stage::Velocity);\n+\n     ComplexResponse() {\n         constructInfrastructure();\n         constructProperty_strength(3.0);\n@@ -39,14 +44,6 @@ private:\n     void constructConnectors() override {\n         constructConnector<Coordinate>("coord");\n     }\n-    void constructOutputs() override {\n-        constructOutput<double>("term_1",\n-                &ComplexResponse::getTerm1, SimTK::Stage::Position);\n-        constructOutput<double>("term_2",\n-                &ComplexResponse::getTerm2, SimTK::Stage::Velocity);\n-        constructOutput<double>("sum", &ComplexResponse::getTotal,\n-                SimTK::Stage::Velocity);\n-    }\n     void extendAddToSystem(MultibodySystem& system) const override {\n         Super::extendAddToSystem(system);\n         addCacheVariable<double>("term_1",\n@@ -73,6 +70,13 @@ public:\n     // Component::getParent.\n     OpenSim_DECLARE_PROPERTY(scaling_factor, double, "Affects each coord.");\n \n+    OpenSim_DECLARE_OUTPUT(total_sum, double, getTotalSum,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(total_term_1, double, getTotalTerm1,\n+            SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(total_term_2, double, getTotalTerm2,\n+            SimTK::Stage::Velocity);\n+\n     double getTotalSum(const State& s) const {\n         const double basalRate = 1.0;\n         double totalSum = 1.0;\n@@ -105,14 +109,6 @@ private:\n             markAsSubcomponent(response.get());\n         }\n     }\n-    void constructOutputs() override {\n-        constructOutput<double>("total_sum",\n-                &AggregateResponse::getTotalSum, SimTK::Stage::Position);\n-        constructOutput<double>("total_term_1",\n-                &AggregateResponse::getTotalTerm1, SimTK::Stage::Velocity);\n-        constructOutput<double>("total_term_2",\n-                &AggregateResponse::getTotalTerm2, SimTK::Stage::Velocity);\n-    }\n };\n \n template <typename T>\ndiff --git a/OpenSim/Sandbox/futureStatesTrajectoryUsage.cpp b/OpenSim/Sandbox/futureStatesTrajectoryUsage.cpp\nnew file mode 100644\nindex 000000000..5036fa902\n--- /dev/null\n+++ b/OpenSim/Sandbox/futureStatesTrajectoryUsage.cpp\n@@ -0,0 +1,45 @@\n+#include <OpenSim/OpenSim.h>\n+\n+using namespace OpenSim;\n+using namespace SimTK;\n+\n+StatesTrajectory simulate(const Model& model, const State& initState,\n+        double finalTime) {\n+\n+    StatesTrajectory states;\n+\n+    SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());\n+    SimTK::TimeStepper ts(model.getSystem(), integrator);\n+    ts.initialize(initState);\n+    ts.setReportAllSignificantStates(true);\n+    integrator.setReturnEveryInternalStep(true);\n+    while (ts.getState().getTime() < finalTime) {\n+        ts.stepTo(finalTime);\n+        // StatesTrajectory API for appending states:\n+        states.append(ts.getState());\n+    }\n+    return states;\n+\n+}\n+\n+int main() {\n+    Model model("gait10dof18musc_subject01.osim");\n+\n+    // Create a StatesTrajectory from a forward simulation.\n+    // ----------------------------------------------------\n+    // To assist with creating interesting (non-zero) coordinate values:\n+    model.updCoordinateSet().get("pelvis_ty").setDefaultLocked(true);\n+    auto& initState = model.initSystem();\n+    StatesTrajectory states = simulate(model, initState, 0.05);\n+\n+    // Use trajectory.\n+    // ---------------\n+    for (const auto& state : states) {\n+        std::cout << state.getTime() << "s: "\n+                  << model.getStateVariableValue(state,\n+                                                 "ankle_r/ankle_angle_r/value")\n+                  << std::endl;\n+    }\n+\n+    return 0;\n+}\ndiff --git a/OpenSim/Simulation/Model/Actuator.cpp b/OpenSim/Simulation/Model/Actuator.cpp\nindex f29afa264..dda5201c8 100644\n--- a/OpenSim/Simulation/Model/Actuator.cpp\n+++ b/OpenSim/Simulation/Model/Actuator.cpp\n@@ -157,12 +157,6 @@ void ScalarActuator::constructProperties()\n     constructProperty_max_control( Infinity);\n }\n \n-void ScalarActuator::constructOutputs() \n-{\n-    constructOutput<double>("actuation", &ScalarActuator::getActuation, SimTK::Stage::Velocity);\n-    constructOutput<double>("speed", &ScalarActuator::getSpeed, SimTK::Stage::Velocity);\n-}\n-\n // Create the underlying computational system component(s) that support the\n // ScalarActuator model component\n void ScalarActuator::extendAddToSystem(SimTK::MultibodySystem& system) const\n@@ -240,4 +234,4 @@ double ScalarActuator::computeOverrideActuation(const SimTK::State& s) const\n     double appliedActuation = getOverrideActuation(s);\n     setActuation(s, appliedActuation);\n     return appliedActuation;\n-}\n\\ No newline at end of file\n+}\ndiff --git a/OpenSim/Simulation/Model/Actuator.h b/OpenSim/Simulation/Model/Actuator.h\nindex 8302873cc..497621a16 100644\n--- a/OpenSim/Simulation/Model/Actuator.h\n+++ b/OpenSim/Simulation/Model/Actuator.h\n@@ -144,6 +144,14 @@ public:\n         "Maximum allowed value for control signal. Used primarily when solving "\n         "for control values.");\n \n+//==============================================================================\n+// OUTPUTS \n+//==============================================================================\n+    OpenSim_DECLARE_OUTPUT(actuation, double, getActuation,\n+            SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(speed, double, getSpeed, SimTK::Stage::Velocity);\n+\n+\n //==============================================================================\n // PUBLIC METHODS\n //==============================================================================\n@@ -245,7 +253,6 @@ protected:\n \n private:\n     void constructProperties() override;\n-    void constructOutputs() override;\n \n //=============================================================================\n };  // END of class ScalarActuator\ndiff --git a/OpenSim/Simulation/Model/Geometry.h b/OpenSim/Simulation/Model/Geometry.h\nindex 9ec846ae3..8ebe2ed95 100644\n--- a/OpenSim/Simulation/Model/Geometry.h\n+++ b/OpenSim/Simulation/Model/Geometry.h\n@@ -103,11 +103,13 @@ public:\n     // will be removed before release 4.0 in favor of a mechanism that \n     // handles local/global/shared Appearance objects\n     /// Convenient access to set Appearance/Color\n+    /// color is RGB, each components is in the range [0, 1].\n     void setColor(const SimTK::Vec3& color) { \n         upd_Appearance().set_color(color); \n     };\n \n     /// Convenient access to get Appearance/Color\n+    /// returns RGB , each components is in the range [0, 1].\n     const SimTK::Vec3& getColor() const { \n         return get_Appearance().get_color(); \n     };\ndiff --git a/OpenSim/Simulation/Model/Model.cpp b/OpenSim/Simulation/Model/Model.cpp\nindex 98d149337..0cda762d0 100644\n--- a/OpenSim/Simulation/Model/Model.cpp\n+++ b/OpenSim/Simulation/Model/Model.cpp\n@@ -2078,17 +2078,3 @@ SimTK::Vec3 Model::calcMassCenterAcceleration(const SimTK::State &s) const\n *\n **/\n \n-void Model::constructOutputs()\n-{\n-    //return the position of the center of mass\n-   constructOutput<SimTK::Vec3>("com_position",\n-       std::bind(&Model::calcMassCenterPosition,this,std::placeholders::_1), SimTK::Stage::Position);\n-   //return the velocity of the center of mass \n-   constructOutput<SimTK::Vec3>("com_velocity",\n-       std::bind(&Model::calcMassCenterVelocity,this,std::placeholders::_1), SimTK::Stage::Velocity);\n-   //return the acceleration of the center of mass\n-   constructOutput<SimTK::Vec3>("com_acceleration",\n-       std::bind(&Model::calcMassCenterAcceleration,this,std::placeholders::_1), SimTK::Stage::Acceleration);\n-    \n-}\n-\ndiff --git a/OpenSim/Simulation/Model/Model.h b/OpenSim/Simulation/Model/Model.h\nindex adc6bb8ae..1f4e8e151 100644\n--- a/OpenSim/Simulation/Model/Model.h\n+++ b/OpenSim/Simulation/Model/Model.h\n@@ -177,6 +177,18 @@ public:\n     OpenSim_DECLARE_UNNAMED_PROPERTY(ModelVisualPreferences,\n         "Visual preferences for this model.");\n \n+//==============================================================================\n+// OUTPUTS\n+//==============================================================================\n+   OpenSim_DECLARE_OUTPUT(com_position, SimTK::Vec3,\n+           calcMassCenterPosition, SimTK::Stage::Position);\n+\n+   OpenSim_DECLARE_OUTPUT(com_velocity, SimTK::Vec3,\n+           calcMassCenterVelocity, SimTK::Stage::Velocity);\n+\n+   OpenSim_DECLARE_OUTPUT(com_acceleration, SimTK::Vec3,\n+           calcMassCenterAcceleration, SimTK::Stage::Acceleration);\n+\n //=============================================================================\n // METHODS\n //=============================================================================\n@@ -960,9 +972,6 @@ private:\n     void constructProperties();\n     void setDefaultProperties();\n \n-    // construct outputs\n-    void constructOutputs() override;\n-\n     // Utility to build a connected graph (tree) of the multibody system\n     void createMultibodyTree();\n \ndiff --git a/OpenSim/Simulation/Model/Muscle.cpp b/OpenSim/Simulation/Model/Muscle.cpp\nindex bbf7f6936..eed4359a7 100644\n--- a/OpenSim/Simulation/Model/Muscle.cpp\n+++ b/OpenSim/Simulation/Model/Muscle.cpp\n@@ -123,86 +123,6 @@ void Muscle::constructProperties()\n     constructProperty_ignore_activation_dynamics(false);\n }\n \n-void Muscle::constructOutputs()\n-{\n-    constructOutput<double>("excitation", &Muscle::getExcitation,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("activation", &Muscle::getActivation,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_length", &Muscle::getFiberLength,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("pennation_angle", &Muscle::getPennationAngle,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("cos_pennation_angle", &Muscle::getCosPennationAngle,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("tendon_length", &Muscle::getTendonLength,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("normalized_fiber_length",\n-                            &Muscle::getNormalizedFiberLength,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("fiber_length_along_tendon",\n-                            &Muscle::getFiberLengthAlongTendon,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("tendon_strain", &Muscle::getTendonStrain,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("passive_force_multiplier",\n-                            &Muscle::getPassiveForceMultiplier,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("active_force_length_multiplier",\n-                            &Muscle::getActiveForceLengthMultiplier,\n-                            SimTK::Stage::Position);\n-    constructOutput<double>("fiber_velocity", &Muscle::getFiberVelocity,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("normalized_fiber_velocity",\n-                            &Muscle::getNormalizedFiberVelocity,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("fiber_velocity_along_tendon",\n-                            &Muscle::getFiberVelocityAlongTendon,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("tendon_velocity", &Muscle::getTendonVelocity,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("force_velocity_multiplier",\n-                            &Muscle::getForceVelocityMultiplier,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("pennation_angular_velocity",\n-                            &Muscle::getPennationAngularVelocity,\n-                            SimTK::Stage::Velocity);\n-    constructOutput<double>("fiber_force", &Muscle::getFiberForce,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_force_along_tendon",\n-                            &Muscle::getFiberForceAlongTendon,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("active_fiber_force", &Muscle::getActiveFiberForce,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("passive_fiber_force", &Muscle::getPassiveFiberForce,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("active_fiber_force_along_tendon",\n-                            &Muscle::getActiveFiberForceAlongTendon,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("passive_fiber_force_along_tendon",\n-                            &Muscle::getPassiveFiberForceAlongTendon,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("tendon_force", &Muscle::getTendonForce,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_stiffness", &Muscle::getFiberStiffness,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_stiffness_along_tendon",\n-                            &Muscle::getFiberStiffnessAlongTendon,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("tendon_stiffness", &Muscle::getTendonStiffness,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("muscle_stiffness", &Muscle::getMuscleStiffness,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_active_power", &Muscle::getFiberActivePower,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("fiber_passive_power", &Muscle::getFiberPassivePower,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("tendon_power", &Muscle::getTendonPower,\n-                            SimTK::Stage::Dynamics);\n-    constructOutput<double>("muscle_power", &Muscle::getMusclePower,\n-                            SimTK::Stage::Dynamics);\n-}\n-\n \n //--------------------------------------------------------------------------\n // MUSCLE PARAMETERS GETTERS AND SETTERS\ndiff --git a/OpenSim/Simulation/Model/Muscle.h b/OpenSim/Simulation/Model/Muscle.h\nindex e3899d99b..95aa72a74 100644\n--- a/OpenSim/Simulation/Model/Muscle.h\n+++ b/OpenSim/Simulation/Model/Muscle.h\n@@ -77,6 +77,74 @@ public:\n     OpenSim_DECLARE_PROPERTY(ignore_activation_dynamics, bool,\n         "Compute muscle dynamics ignoring activation dynamics. Activation is equivalent to excitation.");\n \n+//=============================================================================\n+// OUTPUTS\n+//=============================================================================\n+    OpenSim_DECLARE_OUTPUT(excitation, double, getExcitation,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(activation, double, getActivation,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_length, double, getFiberLength,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(pennation_angle, double, getPennationAngle,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(cos_pennation_angle, double, getCosPennationAngle,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(tendon_length, double, getTendonLength,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(normalized_fiber_length, double,\n+            getNormalizedFiberLength, SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(fiber_length_along_tendon, double,\n+            getFiberLengthAlongTendon, SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(tendon_strain, double, getTendonStrain,\n+            SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(passive_force_multiplier, double,\n+            getPassiveForceMultiplier, SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(active_force_length_multiplier, double,\n+            getActiveForceLengthMultiplier, SimTK::Stage::Position);\n+    OpenSim_DECLARE_OUTPUT(fiber_velocity, double, getFiberVelocity,\n+            SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(normalized_fiber_velocity, double,\n+            getNormalizedFiberVelocity, SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(fiber_velocity_along_tendon, double,\n+            getFiberVelocityAlongTendon, SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(tendon_velocity, double, getTendonVelocity,\n+            SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(force_velocity_multiplier, double,\n+            getForceVelocityMultiplier, SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(pennation_angular_velocity, double,\n+            getPennationAngularVelocity, SimTK::Stage::Velocity);\n+    OpenSim_DECLARE_OUTPUT(fiber_force, double, getFiberForce,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_force_along_tendon, double,\n+            getFiberForceAlongTendon, SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(active_fiber_force, double, getActiveFiberForce,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(passive_fiber_force, double, getPassiveFiberForce,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(active_fiber_force_along_tendon, double,\n+            getActiveFiberForceAlongTendon, SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(passive_fiber_force_along_tendon, double,\n+            getPassiveFiberForceAlongTendon, SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(tendon_force, double, getTendonForce,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_stiffness, double, getFiberStiffness,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_stiffness_along_tendon, double,\n+            getFiberStiffnessAlongTendon, SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(tendon_stiffness, double, getTendonStiffness,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(muscle_stiffness, double, getMuscleStiffness,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_active_power, double, getFiberActivePower,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(fiber_passive_power, double, getFiberPassivePower,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(tendon_power, double, getTendonPower,\n+            SimTK::Stage::Dynamics);\n+    OpenSim_DECLARE_OUTPUT(muscle_power, double, getMusclePower,\n+            SimTK::Stage::Dynamics);\n+\n //=============================================================================\n // PUBLIC METHODS\n //=============================================================================\n@@ -368,7 +436,6 @@ protected:\n private:\n     void setNull();\n     void constructProperties() override;\n-    void constructOutputs() override;\n     void copyData(const Muscle &aMuscle);\n \n     //--------------------------------------------------------------------------\ndiff --git a/OpenSim/Simulation/Model/PathSpring.cpp b/OpenSim/Simulation/Model/PathSpring.cpp\nindex 208353c9b..99230ac55 100644\n--- a/OpenSim/Simulation/Model/PathSpring.cpp\n+++ b/OpenSim/Simulation/Model/PathSpring.cpp\n@@ -70,13 +70,6 @@ void PathSpring::constructProperties()\n     constructProperty_dissipation(SimTK::NaN);\n }\n \n-void PathSpring::constructOutputs()\n-{\n-    constructOutput<double>("stretch", \n-           std::bind(&PathSpring::getStretch, this, std::placeholders::_1),\n-                      SimTK::Stage::Position);\n-}\n-\n //_____________________________________________________________________________\n /*\n  * Set the resting length.\ndiff --git a/OpenSim/Simulation/Model/PathSpring.h b/OpenSim/Simulation/Model/PathSpring.h\nindex 6727dd756..3f4b3ccaf 100644\n--- a/OpenSim/Simulation/Model/PathSpring.h\n+++ b/OpenSim/Simulation/Model/PathSpring.h\n@@ -67,6 +67,11 @@ public:\n         "The GeometryPath defines the set of points and wrapping surface" \n         "interactions that form the path of action of the PathSpring");\n \n+//=============================================================================\n+// OUTPUTS\n+//=============================================================================\n+    OpenSim_DECLARE_OUTPUT(stretch, double, getStretch,\n+            SimTK::Stage::Position);\n \n //==============================================================================\n // PUBLIC METHODS\n@@ -177,7 +182,6 @@ protected:\n \n private:\n     void constructProperties() override;\n-    void constructOutputs() override;\n \n //=============================================================================\n };  // END of class PathSpring\ndiff --git a/OpenSim/Simulation/Model/Probe.cpp b/OpenSim/Simulation/Model/Probe.cpp\nindex 45104de1d..395f55464 100644\n--- a/OpenSim/Simulation/Model/Probe.cpp\n+++ b/OpenSim/Simulation/Model/Probe.cpp\n@@ -120,12 +120,6 @@ void Probe::constructProperties(void)\n     constructProperty_gain(1.0);\n }\n \n-void Probe::constructOutputs()\n-{\n-    constructOutput<SimTK::Vector>("probe_outputs", &Probe::getProbeOutputs,\n-            Stage::Report);\n-}\n-\n //_____________________________________________________________________________\n /**\n  * Create an underlying OpenSim::Probe\ndiff --git a/OpenSim/Simulation/Model/Probe.h b/OpenSim/Simulation/Model/Probe.h\nindex b0178c979..b4877fa13 100644\n--- a/OpenSim/Simulation/Model/Probe.h\n+++ b/OpenSim/Simulation/Model/Probe.h\n@@ -140,6 +140,12 @@ public:\n     OpenSim_DECLARE_PROPERTY(gain, double,\n         "Constant gain to scale the probe output by.");\n \n+//==============================================================================\n+// OUTPUTS\n+//==============================================================================\n+    OpenSim_DECLARE_OUTPUT(probe_outputs, SimTK::Vector, getProbeOutputs,\n+            SimTK::Stage::Report);\n+\n //=============================================================================\n // METHODS\n //=============================================================================\n@@ -224,7 +230,6 @@ protected:\n private:\n     void setNull();\n     void constructProperties() override;\n-    void constructOutputs() override;\n \n \n //=============================================================================\ndiff --git a/OpenSim/Simulation/Model/Umberger2010MuscleMetabolicsProbe.h b/OpenSim/Simulation/Model/Umberger2010MuscleMetabolicsProbe.h\nindex 2daeb3059..951611303 100644\n--- a/OpenSim/Simulation/Model/Umberger2010MuscleMetabolicsProbe.h\n+++ b/OpenSim/Simulation/Model/Umberger2010MuscleMetabolicsProbe.h\n@@ -48,6 +48,11 @@ class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet;\n  *\n  * The discussion here is based on the following papers:\n  *\n+ * <a href="http://dx.doi.org/10.1371/journal.pone.0150378">\n+ * Uchida, T. K., Hicks, J. L., Dembia, C. L., Delp, S. L. (2016). Stretching\n+ * your energetic budget: how tendon compliance affects the metabolic cost of\n+ * running. PLOS ONE 11(3), e0150378.</a>\n+ *\n  * <a href="http://www.ncbi.nlm.nih.gov/pubmed/20356877">\n  * Umberger, B. R. (2010). Stance and swing phase costs in human walking.\n  * J R Soc Interface 7, 1329-40.</a>\n@@ -68,11 +73,11 @@ class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet;\n  * the rate at which heat is liberated plus the rate at which work is done:\\n\n  * <B>Edot = Bdot + sumOfAllMuscles(Adot + Mdot + Sdot + Wdot).</B>\n  *\n- *       - Bdot is the basal heat rate (W).\n- *       - Adot is the activation heat rate (W).\n- *       - Mdot is the maintenance heat rate (W).\n- *       - Sdot is the shortening heat rate (W).\n- *       - Wdot is the mechanical work rate (W).\n+ * - Bdot is the basal heat rate (W).\n+ * - Adot is the activation heat rate (W).\n+ * - Mdot is the maintenance heat rate (W).\n+ * - Sdot is the shortening heat rate (W).\n+ * - Wdot is the mechanical work rate (W).\n  *\n  *\n  * This probe also uses muscle parameters stored in the MetabolicMuscle object for each muscle.\n@@ -89,9 +94,9 @@ class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet;\n  * slow-twitch fibers increases from r to 1. See\n  * <a href="http://www.ncbi.nlm.nih.gov/pubmed/14672571">Bhargava, L.J., Pandy,\n  * M.G., Anderson, F.C. (2004) A phenomenological model for estimating metabolic\n- * energy consumption in muscle contraction. J Biomech 37:81-88</a>. To assume a\n- * constant ratio of slow- and fast-twitch fiber recruitment, set the\n- * \'use_Bhargava_recruitment_model\' property to false.\n+ * energy consumption in muscle contraction. J Biomech 37:81-88</a> and Uchida\n+ * et al. (2016). To assume a constant ratio of slow- and fast-twitch fiber\n+ * recruitment, set the \'use_Bhargava_recruitment_model\' property to false.\n  *\n  *\n  *\n@@ -125,7 +130,6 @@ class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet;\n  * <B>Sdot = m * (-[(alphaS_slow * v_CE_norm * r) + (alphaS_fast * v_CE_norm * (1-r))] * A^2 * S * F_iso)   </B>,   <I>l_CE >  l_CE_opt   &   v_CE >= 0 (concentric / isometric contraction)</I>\\n\n  * <B>Sdot = m * (alphaL * v_CE_norm * A * S)              </B>,   <I>l_CE <= l_CE_opt   &   v_CE <  0 (eccentric contraction)</I>\\n\n  * <B>Sdot = m * (alphaL * v_CE_norm * A * S * F_CE_iso)   </B>,   <I>l_CE >  l_CE_opt   &   v_CE <  0 (eccentric contraction)</I>\n- * \n  *     - <B>A = u          </B>,    <I>u >  a </I>\n  *     - <B>A = (u+a)/2    </B>,    <I>u <= a </I>\n  *\n@@ -166,8 +170,9 @@ class Umberger2010MuscleMetabolicsProbe_MetabolicMuscleParameterSet;\n  * Sdot (if necessary) to ensure Edot > 0 for each muscle. See\n  * <a href="http://www.ncbi.nlm.nih.gov/pubmed/9409483">Constable, J.K.,\n  * Barclay, C.J., Gibbs, C.L. (1997) Energetics of lengthening in mouse and toad\n- * skeletal muscles. J Physiol 505:205-215</a>. To allow muscles to have\n- * negative total power, set the \'forbid_negative_total_power\' property to false.\n+ * skeletal muscles. J Physiol 505:205-215</a> and Uchida et al. (2016). To\n+ * allow muscles to have negative total power, set the\n+ * \'forbid_negative_total_power\' property to false.\n  *\n  *\n  * Note that if enforce_minimum_heat_rate_per_muscle == true AND \ndiff --git a/OpenSim/Simulation/SimbodyEngine/Coordinate.cpp b/OpenSim/Simulation/SimbodyEngine/Coordinate.cpp\nindex db9baae54..32368de58 100644\n--- a/OpenSim/Simulation/SimbodyEngine/Coordinate.cpp\n+++ b/OpenSim/Simulation/SimbodyEngine/Coordinate.cpp\n@@ -638,17 +638,6 @@ void Coordinate::setClamped(SimTK::State& s, bool aLocked) const\n     setModelingOption(s, "is_clamped", (int)aLocked);\n }\n \n-void Coordinate::constructOutputs()\n-{\n-    //return the coordinate value\n-    constructOutput<double>("value", &Coordinate::getValue, Stage::Model);\n-    //return the speed value;\n-    constructOutput<double>("speed", &Coordinate::getSpeedValue, Stage::Model);\n-    //return the acceleration value;\n-    constructOutput<double>("acceleration", &Coordinate::getAccelerationValue,\n-                             Stage::Acceleration);\n-}\n-\n //-----------------------------------------------------------------------------\n // Coordinate::CoordinateStateVariable\n //-----------------------------------------------------------------------------\ndiff --git a/OpenSim/Simulation/SimbodyEngine/Coordinate.h b/OpenSim/Simulation/SimbodyEngine/Coordinate.h\nindex 2e505a7e2..3cdcf34fc 100644\n--- a/OpenSim/Simulation/SimbodyEngine/Coordinate.h\n+++ b/OpenSim/Simulation/SimbodyEngine/Coordinate.h\n@@ -97,6 +97,14 @@ public:\n         "this flag set to false, to dictate the value of unimportant coordinates " \n         "if they are linked via constraints."); \n \n+//==============================================================================\n+// OUTPUTS\n+//==============================================================================\n+    OpenSim_DECLARE_OUTPUT(value, double, getValue, SimTK::Stage::Model);\n+    OpenSim_DECLARE_OUTPUT(speed, double, getSpeedValue, SimTK::Stage::Model);\n+    OpenSim_DECLARE_OUTPUT(acceleration, double, getAccelerationValue,\n+            SimTK::Stage::Acceleration);\n+\n     /** Motion type that describes the motion dictated by the coordinate.\n         Types include: Rotational, Translational and Coupled (both) */\n     enum MotionType\n@@ -309,7 +317,6 @@ private:\n \n     // PRIVATE METHODS implementing the Component interface\n     void constructProperties() override;\n-    void constructOutputs() override;\n     void extendFinalizeFromProperties() override;\n \n     friend class CoordinateCouplerConstraint; \ndiff --git a/OpenSim/Simulation/StatesTrajectory.cpp b/OpenSim/Simulation/StatesTrajectory.cpp\nnew file mode 100644\nindex 000000000..b873c7afe\n--- /dev/null\n+++ b/OpenSim/Simulation/StatesTrajectory.cpp\n@@ -0,0 +1,231 @@\n+/* -------------------------------------------------------------------------- *\n+ *                       OpenSim:  StatesTrajectory.cpp                       *\n+ * -------------------------------------------------------------------------- *\n+ * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *\n+ * See http://opensim.stanford.edu and the NOTICE file for more information.  *\n+ * OpenSim is developed at Stanford University and supported by the US        *\n+ * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *\n+ * through the Warrior Web program.                                           *\n+ *                                                                            *\n+ * Copyright (c) 2016 Stanford University and the Authors                     *\n+ * Author(s): Chris Dembia                                                    *\n+ *                                                                            *\n+ * Licensed under the Apache License, Version 2.0 (the "License"); you may    *\n+ * not use this file except in compliance with the License. You may obtain a  *\n+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *\n+ *                                                                            *\n+ * Unless required by applicable law or agreed to in writing, software        *\n+ * distributed under the License is distributed on an "AS IS" BASIS,          *\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *\n+ * See the License for the specific language governing permissions and        *\n+ * limitations under the License.                                             *\n+ * -------------------------------------------------------------------------- */\n+\n+#include "StatesTrajectory.h"\n+#include <OpenSim/Common/Storage.h>\n+#include <OpenSim/Simulation/Model/Model.h>\n+\n+using namespace OpenSim;\n+\n+size_t StatesTrajectory::getSize() const {\n+    return m_states.size();\n+}\n+\n+void StatesTrajectory::append(const SimTK::State& state) {\n+    if (!m_states.empty()) {\n+\n+        SimTK_APIARGCHECK2_ALWAYS(m_states.back().getTime() <= state.getTime(),\n+                "StatesTrajectory", "append", \n+                "New state\'s time (%f) must be equal to or greater than the "\n+                "time for the last state in the trajectory (%f).",\n+                state.getTime(), m_states.back().getTime()\n+                );\n+\n+        // We assume the trajectory (before appending) is already consistent, \n+        // so we only need to check consistency with a single state in the\n+        // trajectory.\n+        OPENSIM_THROW_IF(!m_states.back().isConsistent(state),\n+          InconsistentState, state.getTime());\n+    }\n+    m_states.push_back(state);\n+}\n+\n+bool StatesTrajectory::hasIntegrity() const {\n+    return isNondecreasingInTime() && isConsistent();\n+}\n+\n+bool StatesTrajectory::isNondecreasingInTime() const {\n+    // An empty or size-1 trajectory necessarily has nondecreasing times.\n+    if (getSize() <= 1) return true;\n+\n+    for (int itime = 1; itime < getSize(); ++itime) {\n+\n+        if (get(itime).getTime() < get(itime - 1).getTime()) {\n+            return false;\n+        }\n+\n+    }\n+    return true;\n+}\n+\n+bool StatesTrajectory::isConsistent() const {\n+    // An empty or size-1 trajectory is necessarily consistent.\n+    if (getSize() <= 1) return true;\n+\n+    const auto& state0 = get(0);\n+\n+    for (int itime = 1; itime < getSize(); ++itime) {\n+\n+        if (!state0.isConsistent(get(itime))) {\n+            return false;\n+        }\n+\n+    }\n+    return true;\n+}\n+\n+bool StatesTrajectory::isCompatibleWith(const Model& model) const {\n+    // An empty trajectory is necessarily compatible.\n+    if (getSize() == 0) return true;\n+\n+    if (!isConsistent()) return false;\n+\n+    // Since we now know all the states are consistent with each other, we only\n+    // need to check if the first one is compatible with the model.\n+    const auto& state0 = get(0);\n+\n+    if (model.getNumStateVariables() != state0.getNY()) {\n+        return false;\n+    }\n+    if (model.getNumCoordinates() != state0.getNQ()) {\n+        return false;\n+    }\n+    if (model.getNumSpeeds() != state0.getNU()) {\n+        return false;\n+    }\n+    // TODO number of constraints.\n+\n+    return true;\n+}\n+\n+StatesTrajectory StatesTrajectory::createFromStatesStorage(\n+        const Model& model,\n+        const Storage& sto,\n+        bool allowMissingColumns,\n+        bool allowExtraColumns) {\n+\n+    // Assemble the required objects.\n+    // ==============================\n+\n+    // This is what we\'ll return.\n+    StatesTrajectory states;\n+\n+    // Make a copy of the model so that we can get a corresponding state.\n+    Model localModel(model);\n+\n+    // We\'ll keep editing this state as we loop through time.\n+    auto state = localModel.initSystem();\n+\n+    // The labels of the columns in the storage file.\n+    const auto& stoLabels = sto.getColumnLabels();\n+    int numDependentColumns = stoLabels.getSize() - 1;\n+\n+    // Error checking.\n+    // ===============\n+    // Angular quantities must be expressed in radians.\n+    // TODO we could also manually convert the necessary coords/speeds to\n+    // radians.\n+    OPENSIM_THROW_IF(sto.isInDegrees(), StatesStorageIsInDegrees);\n+\n+    // If column labels aren\'t unique, It\'s unclear which column the user\n+    // wanted to use for the related state variable.\n+    OPENSIM_THROW_IF(!sto.storageLabelsAreUnique(),\n+            NonUniqueColumnsInStatesStorage);\n+\n+    // To be safe, we don\'t process storages in which individual rows are\n+    // missing values.\n+    OPENSIM_THROW_IF(numDependentColumns != sto.getSmallestNumberOfStates(),\n+            VaryingNumberOfStatesPerRow,\n+            numDependentColumns, sto.getSmallestNumberOfStates());\n+\n+    // Check if states are missing from the Storage.\n+    // ---------------------------------------------\n+    const auto& modelStateNames = localModel.getStateVariableNames();\n+    std::vector<std::string> missingColumnNames;\n+    // Also, assemble the names of the states that we will actually set in the\n+    // trajectory, along with the corresponding state index.\n+    std::map<int, std::string> statesToFillUp;\n+    for (int is = 0; is < modelStateNames.getSize(); ++is) {\n+        // getStateIndex() will check for pre-4.0 column names.\n+        const int stateIndex = sto.getStateIndex(modelStateNames[is]);\n+        if (stateIndex == -1) {\n+            missingColumnNames.push_back(modelStateNames[is]);\n+        } else {\n+            statesToFillUp[stateIndex] = modelStateNames[is];\n+        }\n+    }\n+    OPENSIM_THROW_IF(!allowMissingColumns && !missingColumnNames.empty(),\n+            MissingColumnsInStatesStorage, \n+            localModel.getName(), missingColumnNames);\n+\n+    // Check if the Storage has columns that are not states in the Model.\n+    // ------------------------------------------------------------------\n+    if (!allowExtraColumns) {\n+        if (numDependentColumns > statesToFillUp.size()) {\n+            std::vector<std::string> extraColumnNames;\n+            // We want the actual column names, not the state names; the two\n+            // might be different b/c the state names changed in v4.0.\n+            for (int ic = 1; ic < stoLabels.getSize(); ++ic) {\n+                // Has this label been marked as a model state?\n+                // stateIndex = columnIndex - 1 (b/c of the time column).\n+                if (statesToFillUp.count(ic - 1) == 0) {\n+                    extraColumnNames.push_back(stoLabels[ic]);\n+                }\n+            }\n+            OPENSIM_THROW(ExtraColumnsInStatesStorage, localModel.getName(),\n+                    extraColumnNames);\n+        }\n+    }\n+\n+\n+    // Fill up trajectory.\n+    // ===================\n+\n+    // Reserve the memory we\'ll need to fit all the states.\n+    states.m_states.reserve(sto.getSize());\n+\n+    // Working memory.\n+    SimTK::Vector dependentValues(numDependentColumns);\n+\n+    // Loop through all rows of the Storage.\n+    for (int itime = 0; itime < sto.getSize(); ++itime) {\n+\n+        // Extract data from Storage into the working Vector.\n+        sto.getData(itime, numDependentColumns, dependentValues);\n+\n+        // Set the correct time in the state.\n+        sto.getTime(itime, state.updTime());\n+\n+        // Put in NaNs for state variable values not in the Storage.\n+        for (const auto& stateName : missingColumnNames) {\n+            localModel.setStateVariableValue(state, stateName, SimTK::NaN);\n+        }\n+\n+        // Fill up current State with the data for the current time.\n+        for (const auto& kv : statesToFillUp) {\n+            localModel.setStateVariableValue(state,\n+                    kv.second, dependentValues[kv.first]);\n+        }\n+\n+        // Make a copy of the edited state and put it in the trajectory.\n+        states.append(state);\n+    }\n+\n+    return states;\n+}\n+\n+StatesTrajectory StatesTrajectory::createFromStatesStorage(\n+        const Model& model,\n+        const std::string& filepath) {\n+    return createFromStatesStorage(model, Storage(filepath));\n+}\ndiff --git a/OpenSim/Simulation/StatesTrajectory.h b/OpenSim/Simulation/StatesTrajectory.h\nnew file mode 100644\nindex 000000000..51b0264dc\n--- /dev/null\n+++ b/OpenSim/Simulation/StatesTrajectory.h\n@@ -0,0 +1,465 @@\n+#ifndef OPENSIM_STATES_TRAJECTORY_H_\n+#define OPENSIM_STATES_TRAJECTORY_H_\n+/* -------------------------------------------------------------------------- *\n+ *                       OpenSim:  StatesTrajectory.h                         *\n+ * -------------------------------------------------------------------------- *\n+ * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *\n+ * See http://opensim.stanford.edu and the NOTICE file for more information.  *\n+ * OpenSim is developed at Stanford University and supported by the US        *\n+ * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *\n+ * through the Warrior Web program.                                           *\n+ *                                                                            *\n+ * Copyright (c) 2016 Stanford University and the Authors                     *\n+ * Author(s): Chris Dembia                                                    *\n+ *                                                                            *\n+ * Licensed under the Apache License, Version 2.0 (the "License"); you may    *\n+ * not use this file except in compliance with the License. You may obtain a  *\n+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *\n+ *                                                                            *\n+ * Unless required by applicable law or agreed to in writing, software        *\n+ * distributed under the License is distributed on an "AS IS" BASIS,          *\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *\n+ * See the License for the specific language governing permissions and        *\n+ * limitations under the License.                                             *\n+ * -------------------------------------------------------------------------- */\n+\n+#include <vector>\n+#include <Simbody.h>\n+\n+#include <OpenSim/Common/Exception.h>\n+\n+#include "osimSimulationDLL.h"\n+\n+namespace OpenSim {\n+\n+class Storage;\n+class Model;\n+\n+// Design note: This class is part of OpenSim instead of Simbody since Simbody\n+// users are likely to be interested in a more general State container that\n+// doesn\'t assume the states are sequential in time.\n+\n+/** A sequence of SimTK::State%s that can be saved to a plain-text OSTATES\n+ * file.  The trajectory can also be populated from such a file. You may obtain\n+ * a StatesTrajectory from a simulation, or other numerical methods whose task\n+ * is to produce a trajectory of states. Users can modify the trajectory by\n+ * appending states to it, but users cannot modify the individual states that\n+ * are already in the trajectory.\n+ *\n+ * This class was introduced in OpenSim version 4.0, and enables scripting\n+ * (Python/MATLAB) and C++ users to postprocess their results with greater ease\n+ * and more versatility than with an Analysis.\n+ *\n+ * @note This class is a work in progress. The ability to read and write a\n+ * StatesTrajectory to an OSTATES is not available yet, even though the\n+ * documentation is written as if this ability exists.\n+ *\n+ * ### Guarantees\n+ * This class is designed to ensure the following:\n+ * - The states are ordered nondecreasing in time (adjacent states *can* have\n+ *   the same time).\n+ * - All states in the trajectory are consistent with each other (see\n+ *   isConsistent()).\n+ *\n+ * @note These gaurantees apply when using this class through C++, Java,\n+ * or the %OpenSim GUI, but **not** through Python or MATLAB. This is because\n+ * Python and MATLAB do not enforce constness and thus allow modifying the\n+ * trajectory.\n+ *\n+ * ### Using with a %Model \n+ * A StatesTrajectory is not very useful on its own, since neither the\n+ * trajectory nor the contained states know of the names that the Component%s\n+ * give to the state variables. You probably want to use the trajectory with an\n+ * OpenSim::Model, through which the state variables have a meaning (e.g.,\n+ * `model.getStateVariableValue(states[0], "soleus_r/activation")`).\n+ *\n+ * SimTK::State%s have a tight association with a specific OpenSim::Model\n+ * (actually, with the SimTK::System within an OpenSim::Model). However,\n+ * neither the StatesTrajectory nor the OSTATES file knows the model to which\n+ * it corresponds. So, for example, you could use a single StatesTrajectory\n+ * with a generic gait2392 model as well as with a scaled (subject-specific)\n+ * gait2392 model. This flexibility may be beneficial in some scenarios, but\n+ * also allows one to accidentally use the wrong model with a given states\n+ * trajectory, potentially leading to silent errors that could compromise a\n+ * scientific study.\n+ *\n+ * To increase your confidence that a StatesTrajectory matches a given Model,\n+ * you can perform some weak checks with isCompatibleWith().\n+ *\n+ * ### File format\n+ * StatesTrajectory files use the file extension `.ostates`, with the XML\n+ * format. Therefore, you could theoretically edit a StatesTrajectory file in\n+ * a typical text editing program, or in Python/MATLAB using XML libraries\n+ * (such a process is is likely to be painful; consider using the\n+ * createFromStatesStorage() utility instead).\n+ *\n+ * A SimTK::State object contains many different types of data, but only some\n+ * are saved into the OSTATES file:\n+ * \n+ * type of data                 | saved in OSTATES?\n+ * ---------------------------- | -----------------\n+ * (continuous) state variables | yes\n+ * discrete state variables     | yes\n+ * modeling options             | yes\n+ * cache variables              | no\n+ *\n+ * The cache variables (e.g., total system mass, control signals) are not saved\n+ * to the OSTATES file because they can be computed from the state variables\n+ * and are not necessary for describing the state of the system (see\n+ * Component::addStateVariable).\n+ *\n+ * %OpenSim Object%s (Model OSIM files, Tool setup files) also use an\n+ * XML format, but that format is *completely unrelated* to the XML format used\n+ * for OSTATES files.\n+ *\n+ * ### Usage\n+ * Here are a few basic things you can do with a StatesTrajectory, assuming you\n+ * already have one:\n+ * @code{.cpp}\n+ * StatesTrajectory states = getStatesTrajectorySomehow();\n+ * const double numStates = states.getSize();\n+ * const double initialTime = states[0].getTime();\n+ * const double finalTime = states.back().getTime();\n+ * @endcode\n+ *\n+ * Without a model, you can access the state variable values, but you won\'t\n+ * know the identity of such state variables.\n+ * @code{.cpp}\n+ * int numGeneralizedCoordinates = states[0].getNQ();\n+ * const SimTK::Vector& generalizedCoordinateValues = states[0].getQ();\n+ * @endcode\n+ *\n+ * To do most things with the StatesTrajectory, you\'ll need a model as well as\n+ * its underlying SimTK::System. **It is therefore required that you call\n+ * `Model::initSystem()` before you try to use any states with the model**:\n+ * @code{.cpp}\n+ * Model model("subject01.osim");\n+ * model.initSystem();\n+ * double knee_angle = model.getStateVariableValue(states[0], "knee/flexion/value");\n+ * Vec3 com = model.calcMassCenterPosition(states[0]);\n+ * @endcode\n+ *\n+ * Depending on the quantity you want to obtain, you may also need to realize\n+ * the state to a certain stage:\n+ * @code{.cpp}\n+ * model.getMultibodySystem().realize(states[0], SimTK::Stage::Velocity);\n+ * model.getMuscles().get("soleus_r").getActivation(states[0]);\n+ * @endcode\n+ *\n+ * You can iterate through a trajectory to access the value of a state variable\n+ * at each time in the trajectory.\n+ * @code{.cpp}\n+ * for (const auto& state : states) {\n+ *     std::cout << state.getTime() << " "\n+ *               << model.getStateVariableValue(state, "knee/flexion/value")\n+ *               << std::endl;\n+ * }\n+ * @endcode\n+ */\n+class OSIMSIMULATION_API StatesTrajectory {\n+public:\n+    /** Create an empty trajectory of states. */\n+    StatesTrajectory() {}\n+\n+    /** The number of SimTK::State%s in the trajectory. */\n+    size_t getSize() const;\n+\n+    /// @name Accessing individual SimTK::State%s\n+    /// @{\n+    /** Get a const reference to the state at a given index in the trajectory.\n+     * Here\'s an example of getting a state variable value from the first state\n+     * in the trajectory: \n+     * @code{.cpp}\n+     * Model model("subject01.osim");\n+     * const StatesTrajectory states = getStatesTrajectorySomehow();\n+     * const auto& state = states[0];\n+     * model.getStateVariableValue(state, "knee/flexion/value");\n+     * @endcode\n+     * This function does not check if the index is larger than the size of\n+     * the trajectory; see get() if you want this check. */\n+    const SimTK::State& operator[](size_t index) const {\n+        return m_states[index];\n+    }\n+    /** Get a const reference to the state at a given index in the trajectory.\n+\n+     * @throws IndexOutOfRange If the index is greater than the size of the\n+     *                         trajectory.\n+     */\n+    const SimTK::State& get(size_t index) const {\n+        try {\n+            return m_states.at(index);\n+        } catch (const std::out_of_range&) {\n+            OPENSIM_THROW(IndexOutOfRange, index, 0, m_states.size() - 1);\n+        }\n+    }\n+    /** Get a const reference to the first state in the trajectory. */\n+    const SimTK::State& front() const { \n+        return m_states.front();\n+    }\n+    /** Get a const reference to the last state in the trajectory. */\n+    const SimTK::State& back() const { \n+        return m_states.back();\n+    }\n+    /// @}\n+    \n+    /** Iterator type that does not allow modifying the trajectory.\n+     * Most users do not need to understand what this is. */\n+    typedef std::vector<SimTK::State>::const_iterator const_iterator;\n+\n+    /** A helper type to allow using range for loops over a subset of the\n+     * trajectory. */\n+    typedef SimTK::IteratorRange<const_iterator> IteratorRange;\n+\n+    /// @name Iterating through the trajectory\n+    /// @{\n+\n+    /** Iterator pointing to first SimTK::State; does not allow modifying the\n+     * states. Allows using this class in a range for loop. */\n+    const_iterator begin() const { return m_states.cbegin(); }\n+    /** Iterator pointing past the end of the trajectory. Allows using this\n+     * class in a range for loop. */\n+    const_iterator end() const { return m_states.cend(); }\n+    /// @}\n+\n+    /// @name Populating the trajectory with states\n+    /// @{\n+    /** Append a SimTK::State to this trajectory.\n+     * This function ensures that the time in the new SimTK::State is\n+     * greater than the time in the last SimTK::State in the trajectory.\n+     *\n+     * The state that ends up in the trajectory is a deep copy of the one\n+     * passed in.\n+     */\n+    void append(const SimTK::State& state);\n+    /// @}\n+\n+    /// @name Checks for integrity\n+    /// @{\n+\n+    /** Checks isNondecreasingInTime() and isConsistent().\n+     * The design of this class is such that this method should always return\n+     * true. This check may be more useful in Python or MATLAB, in which it\'s\n+     * possible to edit the trajectory such that this method could return\n+     * false.  */\n+    // TODO better name?\n+    bool hasIntegrity() const;\n+\n+    /** Returns true if times are non-decreasing; false otherwise. */\n+    bool isNondecreasingInTime() const;\n+\n+    /** Checks if the states have the same number of state variables,\n+     * constraints, etc. Returns true if the following quantities are the same\n+     * for all states in the trajectory:\n+     * - number of generalized coordinates (Q\'s)\n+     * - number of generalized speeds (U\'s)\n+     * - number of auxiliary state variables (Z\'s)\n+     * - number of position constraints (QErr\'s)\n+     * - number of velocity constraints (UErr\'s)\n+     * - number of acceleration constraints (UDotErr\'s)\n+     * - number of constraint Lagrange multipliers\n+     * - number of event triggers\n+     *\n+     * Returns false otherwise.\n+     */\n+    // TODO an option to throw an exception with detailed information about the\n+    // mismatch?\n+    bool isConsistent() const;\n+\n+    /** Weak check for if the trajectory can be used with the given model.\n+     * Returns true if the trajectory isConsistent() and if the following\n+     * quantities are the same:\n+     * - number of model state variables and number of Y\'s in the state \n+     * - number of coordinates in the model and number of Q\'s in state\n+     * - number of speeds in the model and number of U\'s in state\n+     *\n+     * Returns false otherwise. This method **cannot** gaurantee that the\n+     * trajectory will work with the given model, and makes no attempt to\n+     * determine if the trajectory was generated with the given model.\n+     */\n+    bool isCompatibleWith(const Model& model) const;\n+    /// @}\n+\n+private:\n+\n+    std::vector<SimTK::State> m_states;\n+\n+public:\n+\n+    /** Thrown when trying to append a state that is not consistent with the\n+     * rest of the trajectory. */\n+    class InconsistentState : public OpenSim::Exception {\n+    public:\n+        InconsistentState(const std::string& file, size_t line,\n+                const std::string& func, const double& stateTime) :\n+                OpenSim::Exception(file, line, func) {\n+            std::ostringstream msg;\n+            msg << "Cannot append the provided state (at time = " <<\n+                stateTime << " seconds) to the trajectory because it is " <<\n+                "inconsistent with the trajectory.";\n+            addMessage(msg.str());\n+        }\n+    };\n+\n+    /** Thrown when trying to create a StatesTrajectory from a states Storage, and\n+     * the Storage does not contain a column for every continuous state variable.\n+     * */\n+    class MissingColumnsInStatesStorage : public OpenSim::Exception {\n+    public:\n+        MissingColumnsInStatesStorage(const std::string& file, size_t line,\n+                const std::string& func,\n+                const std::string& modelName,\n+                std::vector<std::string> missingStates) :\n+                OpenSim::Exception(file, line, func) {\n+            std::string msg = "The following ";\n+            msg += std::to_string(missingStates.size()) + " states from Model \'";\n+            msg += modelName + "\' are missing from the states Storage:\\n";\n+            for (int i = 0; i < (missingStates.size() - 1); ++i) {\n+                msg += "    " + missingStates[i] + "\\n";\n+            }\n+            msg += "    " + missingStates.back();\n+    \n+            addMessage(msg);\n+        }\n+    };\n+    \n+    /** Thrown when trying to create a StatesTrajectory from a states Storage, and\n+     * the Storage contains columns that do not correspond to continuous state\n+     * variables.\n+     * */\n+    class ExtraColumnsInStatesStorage : public OpenSim::Exception {\n+    public:\n+        ExtraColumnsInStatesStorage(\n+                const std::string& file, size_t line,\n+                const std::string& func,\n+                const std::string& modelName,\n+                std::vector<std::string> extraStates) :\n+                OpenSim::Exception(file, line, func) {\n+            std::string msg = "The following ";\n+            msg += std::to_string(extraStates.size()) + " columns from the ";\n+            msg += "states Storage are not states in Model \'" + modelName + "\':\\n";\n+            for (int i = 0; i < (extraStates.size() - 1); ++i) {\n+                msg += "    " + extraStates[i] + "\\n";\n+            }\n+            msg += "    " + extraStates.back();\n+    \n+            addMessage(msg);\n+        }\n+    };\n+    \n+    /** Thrown by createFromStatesStorage(). */\n+    class NonUniqueColumnsInStatesStorage : public OpenSim::Exception {\n+    public:\n+        NonUniqueColumnsInStatesStorage(const std::string& file, size_t line,\n+                const std::string& func) : OpenSim::Exception(file, line, func) {\n+            addMessage("States Storage column labels are not unique.");\n+        }\n+    };\n+    \n+    /** Thrown by createFromStatesStorage(). */\n+    class StatesStorageIsInDegrees : public OpenSim::Exception {\n+    public:\n+        StatesStorageIsInDegrees(const std::string& file, size_t line,\n+                const std::string& func) : OpenSim::Exception(file, line, func) {\n+            addMessage("States Storage is in degrees, but this is inappropriate "\n+                    "for creating a StatesTrajectory. Edit the Storage so that "\n+                    "angles are in radians, and set \'inDegrees\' to "\n+                    "no in the header.");\n+        }\n+    };\n+    \n+    /** Thrown by createFromStatesStorage(). */\n+    class VaryingNumberOfStatesPerRow : public OpenSim::Exception {\n+    public:\n+        VaryingNumberOfStatesPerRow(const std::string& file, size_t line,\n+                const std::string& func,\n+                int numDepColumns, int smallestNumStates) :\n+                    OpenSim::Exception(file, line, func) {\n+            std::string msg = "States Storage has varying number of entries ";\n+            msg += "per row (from " + std::to_string(smallestNumStates) + " to ";\n+            msg += std::to_string(numDepColumns) + "). You must provide a ";\n+            msg += "States Storage that has the same number ";\n+            msg += "of entires in every row.";\n+            addMessage(msg);\n+        }\n+    };\n+\n+    /// @name Create partial trajectory from pre-4.0 files\n+    /// @{\n+    /** Create a partial trajectory of States from a (pre-4.0) states Storage\n+     * object. The resulting StatesTrajectory will restore continuous state\n+     * variable values, but not discrete state variable values, modeling\n+     * option values, etc. Also, keep in mind that states Storage files usually\n+     * do not contain the state values to full precision, and thus cannot\n+     * exactly reproduce results from the initial state trajectory; constraints\n+     * may not be satisfied, etc.\n+     * \n+     * #### History\n+     * Before OpenSim 4.0, the only way to save states to a file was as\n+     * a Storage file, typically called a states storage file and named\n+     * `*_states.sto`. You can use this function to create a StatesTrajectory\n+     * from such a Storage file. OpenSim 4.0 introduced the ability to save and\n+     * read a complete StatesTrajectory to/from an OSTATES file, and so this\n+     * function should only be used when you are stuck with pre-4.0 files.\n+     *\n+     * @note The naming convention for state variables changed in OpenSim v4.0;\n+     * `ankle_r/ankle_angle_r/speed` used to be `ankle_angle_r_u`,\n+     * `soleus_r/activation` used to be `soleus_r.activation`, etc. This\n+     * function can handle %Storage column labels that use the pre-v4.0 naming\n+     * convention.\n+     * \n+     * @param model The Model to which the states belong. A Model is necessary\n+     *      since the storage file lists the state variables by name.\n+     * @param sto The Storage object containing state values.\n+     * @param allowMissingColumns If false, throws exception if there are\n+     *      continuous state variables in the Model for which there is no\n+     *      column in the Storage. If true, no exception is thrown but such\n+     *      state variables are set to NaN.\n+     * @param allowExtraColumns If false, throws exception if there are\n+     *      columns in the Storage that do not correspond to continuous state\n+     *      variables in the Model. If true, such columns of the Storage are\n+     *      ignored.\n+     *\n+     * #### Usage\n+     * Here is how you might use this function in python:\n+     * @code{.py}\n+     * import opensim\n+     * model = opensim.Model("subject01.osim")\n+     * model.initSystem()\n+     * sto = opensim.Storage("subject01_states.sto")\n+     * states = opensim.StatesTrajectory.createFromStatesStorage(model, sto)\n+     * print(states[0].getTime())\n+     * print(model.getStateVariableValue(states[0], "knee/flexion/value"))\n+     * @endcode\n+     * \n+     * @throws MissingColumnsInStatesStorage See the description of the\n+     *      `allowMissingColumns` argument.\n+     * \n+     * @throws ExtraColumnsInStatesStorage See the description of the\n+     *      `allowExtraColumns` argument.\n+     *\n+     * @throws NonUniqueColumnsInStatesStorage Thrown if multiple columns in\n+     *      the Storage have the same name.\n+     * \n+     * @throws StatesStorageIsInDegrees Thrown if the Storage is in degrees\n+     *      (inDegrees=yes); angular quantities must use radians to properly\n+     *      create the trajectory.\n+     *\n+     * @throws VaryingNumberOfStatesPerRow Thrown if the rows of the storage\n+     *      don\'t all have the same number of entries.\n+     */\n+    static StatesTrajectory createFromStatesStorage(const Model& model,\n+            const Storage& sto,\n+            bool allowMissingColumns = false,\n+            bool allowExtraColumns = false);\n+\n+    /** Convenience form of createFromStatesStorage() that takes the path to a\n+     * Storage file instead of a Storage object. This convenience form uses the\n+     * default values for `allowMissingColumns` and `allowExtraColumns`. */\n+    static StatesTrajectory createFromStatesStorage(const Model& model,\n+            const std::string& filepath);\n+    /// @}\n+};\n+\n+} // namespace\n+\n+#endif // OPENSIM_STATES_TRAJECTORY_H_\ndiff --git a/OpenSim/Simulation/Test/CMakeLists.txt b/OpenSim/Simulation/Test/CMakeLists.txt\nindex 4dfdfc1a1..488bf823d 100644\n--- a/OpenSim/Simulation/Test/CMakeLists.txt\n+++ b/OpenSim/Simulation/Test/CMakeLists.txt\n@@ -7,3 +7,5 @@ OpenSimAddTests(\n     DATAFILES ${TEST_FILES}\n     LINKLIBS osimCommon osimSimulation osimAnalyses osimActuators osimLepton\n     )\n+\n+OpenSimCopySharedTestFiles(std_subject01_walk1_states.sto)\ndiff --git a/OpenSim/Simulation/Test/testAssemblySolver.cpp b/OpenSim/Simulation/Test/testAssemblySolver.cpp\nindex d76bde1d7..dc7787930 100644\n--- a/OpenSim/Simulation/Test/testAssemblySolver.cpp\n+++ b/OpenSim/Simulation/Test/testAssemblySolver.cpp\n@@ -59,7 +59,7 @@ int main()\n //==========================================================================================================\n void testAssembleModelWithConstraints(string modelFile)\n {\n-    double accuracy = 1e-6;\n+    double accuracy = 1e-5;\n     using namespace SimTK;\n \n     cout << "\\n****************************************************************************" << endl;\n@@ -177,6 +177,11 @@ void testAssembleModelWithConstraints(string modelFile)\n \n     model.equilibrateMuscles(state);\n \n+    // set default (properties) which capture an accurate snapshot of the model\n+    // prior to simulation.\n+    model.setPropertiesFromState(state);\n+    state = model.initSystem();\n+\n     //==========================================================================================================\n     // Integrate forward and init the state and update defaults to make sure\n     // assembler is not effecting anything more than the pose.\n@@ -184,11 +189,7 @@ void testAssembleModelWithConstraints(string modelFile)\n     integrator.setAccuracy(accuracy);\n     Manager manager(model, integrator);\n     manager.setInitialTime(0.0);\n-    manager.setFinalTime(0.1);\n-\n-    // set default (properties) which capture an accurate snapshot of the model\n-    // prior to simulation.\n-    model.setPropertiesFromState(state);\n+    manager.setFinalTime(0.05);\n \n     // Simulate forward in time\n     manager.integrate(state);\ndiff --git a/OpenSim/Simulation/Test/testStatesTrajectory.cpp b/OpenSim/Simulation/Test/testStatesTrajectory.cpp\nnew file mode 100644\nindex 000000000..6ee051dd1\n--- /dev/null\n+++ b/OpenSim/Simulation/Test/testStatesTrajectory.cpp\n@@ -0,0 +1,678 @@\n+/* -------------------------------------------------------------------------- *\n+ *                     OpenSim:  testStatesTrajectory.cpp                     *\n+ * -------------------------------------------------------------------------- *\n+ * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *\n+ * See http://opensim.stanford.edu and the NOTICE file for more information.  *\n+ * OpenSim is developed at Stanford University and supported by the US        *\n+ * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *\n+ * through the Warrior Web program.                                           *\n+ *                                                                            *\n+ * Copyright (c) 2016 Stanford University and the Authors                     *\n+ * Author(s): Chris Dembia                                                    *\n+ *                                                                            *\n+ * Licensed under the Apache License, Version 2.0 (the "License"); you may    *\n+ * not use this file except in compliance with the License. You may obtain a  *\n+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *\n+ *                                                                            *\n+ * Unless required by applicable law or agreed to in writing, software        *\n+ * distributed under the License is distributed on an "AS IS" BASIS,          *\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *\n+ * See the License for the specific language governing permissions and        *\n+ * limitations under the License.                                             *\n+ * -------------------------------------------------------------------------- */\n+\n+#include <OpenSim/Simulation/osimSimulation.h>\n+#include <OpenSim/Common/Constant.h>\n+#include <OpenSim/Common/LoadOpenSimLibrary.h>\n+#include <random>\n+#include <cstdio>\n+\n+using namespace OpenSim;\n+using namespace SimTK;\n+\n+// Small to-do\'s:\n+// TODO nondecreasing or increasing? might affect upper_bound/lower_bound.\n+// TODO detailed exceptions when integrity checks fail.\n+// TODO currently, one gets segfaults if state is not realized.\n+// TODO accessing acceleration-level outputs.\n+\n+// Big to-do\'s:\n+// TODO convert to data table (specify which columns).\n+// TODO append two StateTrajectories together.\n+// TODO test modeling options (locked coordinates, etc.)\n+// TODO store a model within a StatesTrajectory.\n+\n+const std::string statesStoFname = "testStatesTrajectory_readStorage_states.sto";\n+const std::string pre40StoFname = "std_subject01_walk1_states.sto";\n+\n+// Helper function to get a state variable value from a storage file.\n+Real getStorageEntry(const Storage& sto,\n+        const int timeIndex, const std::string& columnName) {\n+    Real value;\n+    const int columnIndex = sto.getStateIndex(columnName);\n+    sto.getData(timeIndex, columnIndex, value);\n+    return value;\n+}\n+\n+void testPopulateTrajectory() {\n+    Model model("gait2354_simbody.osim");\n+\n+    // To assist with creating interesting (non-zero) coordinate values:\n+    model.updCoordinateSet().get("pelvis_ty").setDefaultLocked(true);\n+\n+    auto& state = model.initSystem();\n+\n+    SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());\n+    SimTK::TimeStepper ts(model.getSystem(), integrator);\n+    ts.initialize(state);\n+    ts.setReportAllSignificantStates(true);\n+    integrator.setReturnEveryInternalStep(true);\n+\n+    StatesTrajectory states;\n+    const double finalTime = 0.05;\n+    std::vector<double> times;\n+    while (ts.getState().getTime() < finalTime) {\n+        ts.stepTo(finalTime);\n+        times.push_back(ts.getState().getTime());\n+        // StatesTrajectory API for appending states:\n+        states.append(ts.getState());\n+    }\n+\n+    // Make sure we have all the states\n+    SimTK_TEST_EQ((int)states.getSize(), (int)times.size());\n+    // ...and that they aren\'t all just references to the same single state.\n+    for (int i = 0; i < states.getSize(); ++i) {\n+        SimTK_TEST_EQ(states[i].getTime(), times[i]);\n+    }\n+\n+}\n+\n+void testFrontBack() {\n+    Model model("arm26.osim");\n+    const auto& state = model.initSystem();\n+    StatesTrajectory states;\n+    states.append(state);\n+    states.append(state);\n+    states.append(state);\n+\n+    SimTK_TEST(&states.front() == &states[0]);\n+    SimTK_TEST(&states.back() == &states[2]);\n+}\n+\n+// Create states storage file to for states storage tests.\n+void createStateStorageFile() {\n+\n+    Model model("gait2354_simbody.osim");\n+\n+    // To assist with creating interesting (non-zero) coordinate values:\n+    model.updCoordinateSet().get("pelvis_ty").setDefaultLocked(true);\n+\n+    // Randomly assign muscle excitations to create interesting activation\n+    // histories.\n+    auto* controller = new PrescribedController();\n+    // For consistent results, use same seed each time.\n+    std::default_random_engine generator(0); \n+    // Uniform distribution between 0.1 and 0.9.\n+    std::uniform_real_distribution<double> distribution(0.1, 0.8);\n+\n+    for (int im = 0; im < model.getMuscles().getSize(); ++im) {\n+        controller->addActuator(model.getMuscles()[im]);\n+        controller->prescribeControlForActuator(\n+            model.getMuscles()[im].getName(),\n+            new Constant(distribution(generator))\n+            );\n+    }\n+\n+    model.addController(controller);\n+\n+    auto& initState = model.initSystem();\n+    SimTK::RungeKuttaMersonIntegrator integrator(model.getSystem());\n+    Manager manager(model, integrator);\n+    manager.setFinalTime(0.15);\n+    manager.integrate(initState);\n+    manager.getStateStorage().print(statesStoFname);\n+}\n+\n+void testFromStatesStorageGivesCorrectStates() {\n+\n+    // Read in trajectory.\n+    // -------------------\n+    Model model("gait2354_simbody.osim");\n+\n+    Storage sto(statesStoFname);\n+\n+    // It\'s important that we have not yet initialized the model, \n+    // since `createFromStatesStorage()` should be able to work with such a\n+    // model.\n+    auto states = StatesTrajectory::createFromStatesStorage(model, sto);\n+\n+    // However, we eventually *do* need to call initSystem() to make use of the\n+    // trajectory with the model.\n+    model.initSystem();\n+\n+    // Test that the states are correct, and also that the iterator works.\n+    // -------------------------------------------------------------------\n+    int itime = 0;\n+    double currTime;\n+    for (const auto& state : states) {\n+        // Time.\n+        sto.getTime(itime, currTime);\n+        SimTK_TEST_EQ(currTime, state.getTime());\n+\n+        // Multibody states.\n+        for (int ic = 0; ic < model.getCoordinateSet().getSize(); ++ic) {\n+            const auto& coord = model.getCoordinateSet().get(ic);\n+            auto coordName = coord.getName();\n+            auto jointName = coord.getJoint().getName();\n+            auto coordPath = jointName + "/" + coordName;\n+            // Coordinate.\n+            SimTK_TEST_EQ(getStorageEntry(sto, itime, coordPath + "/value"),\n+                    coord.getValue(state));\n+\n+            // Speed.\n+            SimTK_TEST_EQ(getStorageEntry(sto, itime, coordPath + "/speed"),\n+                    coord.getSpeedValue(state));\n+        }\n+\n+        // Muscle states.\n+        for (int im = 0; im < model.getMuscles().getSize(); ++im) {\n+            const auto& muscle = model.getMuscles().get(im);\n+            auto muscleName = muscle.getName();\n+\n+            // Activation.\n+            {\n+                std::string stateVarName = muscleName + "/activation";\n+                SimTK_TEST_EQ(\n+                        getStorageEntry(sto, itime, stateVarName),\n+                        muscle.getStateVariableValue(state, stateVarName));\n+            }\n+\n+            // Fiber length.\n+            {\n+                std::string stateVarName = muscleName + "/fiber_length";\n+                SimTK_TEST_EQ(\n+                        getStorageEntry(sto, itime, stateVarName), \n+                        muscle.getStateVariableValue(state, stateVarName));\n+            }\n+\n+        }\n+\n+        // More complicated computation based on state.\n+        // These calculations require that the state is realized to velocity.\n+        model.getMultibodySystem().realize(state, SimTK::Stage::Velocity);\n+\n+        for (int im = 0; im < model.getMuscles().getSize(); ++im) {\n+            const auto& muscle = model.getMuscles().get(im);\n+            auto muscleName = muscle.getName();\n+            SimTK_TEST(!SimTK::isNaN(muscle.getFiberForce(state)));\n+        }\n+\n+        auto loc = model.getBodySet().get("tibia_r")\n+            .findLocationInAnotherFrame(state,\n+                    SimTK::Vec3(1, 0.5, 0.25),\n+                    model.getGround());\n+        SimTK_TEST(!loc.isNaN());\n+\n+        SimTK_TEST(!model.calcMassCenterVelocity(state).isNaN());\n+\n+        // TODO acceleration-level stuff gives segfault.\n+        // TODO model.getMultibodySystem().realize(state, SimTK::Stage::Acceleration);\n+        // TODO SimTK_TEST(!model.calcMassCenterAcceleration(state).isNaN());\n+\n+        itime++;\n+    }\n+}\n+\n+Storage newStorageWithRemovedRows(const Storage& origSto,\n+        const std::set<int>& rowsToRemove) {\n+    Storage sto(1000);\n+    auto labels = origSto.getColumnLabels();\n+    auto numOrigColumns = origSto.getColumnLabels().getSize() - 1;\n+\n+    // Remove in reverse order so it\'s easier to keep track of indices.\n+     for (auto it = rowsToRemove.rbegin(); it != rowsToRemove.rend(); ++it) {\n+         labels.remove(*it);\n+     }\n+    sto.setColumnLabels(labels);\n+\n+    double time;\n+    for (int itime = 0; itime < origSto.getSize(); ++itime) {\n+        SimTK::Vector rowData(numOrigColumns);\n+        origSto.getData(itime, numOrigColumns, rowData);\n+\n+        SimTK::Vector newRowData(numOrigColumns - (int)rowsToRemove.size());\n+        int iNew = 0;\n+        for (int iOrig = 0; iOrig < numOrigColumns; ++iOrig) {\n+            if (rowsToRemove.count(iOrig) == 0) {\n+                newRowData[iNew] = rowData[iOrig];\n+                ++iNew;\n+            }\n+        }\n+\n+        origSto.getTime(itime, time);\n+        sto.append(time, newRowData);\n+    }\n+    return sto;\n+}\n+\n+void testFromStatesStorageInconsistentModel(const std::string &stoFilepath) {\n+\n+    // States are missing from the Storage.\n+    // ------------------------------------\n+    {\n+        Model model("gait2354_simbody.osim");\n+        // Needed for getting state variable names.\n+        model.initSystem();\n+\n+        const auto stateNames = model.getStateVariableNames();\n+        Storage sto(stoFilepath);\n+        // So the test doesn\'t take so long.\n+        sto.resampleLinear((sto.getLastTime() - sto.getFirstTime()) / 10);\n+\n+        // Create new Storage with fewer columns.\n+        auto labels = sto.getColumnLabels();\n+\n+        auto origLabel10 = stateNames[10];\n+        auto origLabel15 = stateNames[15];\n+        Storage stoMissingCols = newStorageWithRemovedRows(sto, {\n+                // gymnastics to be compatible with pre-v4.0 column names:\n+                sto.getStateIndex(origLabel10) + 1,\n+                sto.getStateIndex(origLabel15) + 1});\n+\n+        // Test that an exception is thrown.\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, stoMissingCols),\n+                StatesTrajectory::MissingColumnsInStatesStorage\n+                );\n+        // Check some other similar calls.\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, stoMissingCols,\n+                    false, true),\n+                StatesTrajectory::MissingColumnsInStatesStorage\n+                );\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, stoMissingCols,\n+                    false, false),\n+                StatesTrajectory::MissingColumnsInStatesStorage\n+                );\n+\n+        // No exception if allowing missing columns.\n+        // The unspecified states are set to NaN (for at least two random\n+        // states).\n+        auto states = StatesTrajectory::createFromStatesStorage(\n+                model, stoMissingCols, true);\n+        SimTK_TEST(SimTK::isNaN(\n+                    model.getStateVariableValue(states[0], origLabel10)));\n+        SimTK_TEST(SimTK::isNaN(\n+                    model.getStateVariableValue(states[4], origLabel15)));\n+        // Behavior is independent of value for allowMissingColumns.\n+        StatesTrajectory::createFromStatesStorage(model, stoMissingCols,\n+                true, true);\n+        StatesTrajectory::createFromStatesStorage(model, stoMissingCols,\n+                true, false);\n+    }\n+\n+    // States are missing from the Model.\n+    // ----------------------------------\n+    {\n+        Model model("gait2354_simbody.osim");\n+        Storage sto(stoFilepath);\n+        // So the test doesn\'t take so long.\n+        sto.resampleLinear((sto.getLastTime() - sto.getFirstTime()) / 10);\n+\n+        // Remove a few of the muscles.\n+        model.updForceSet().remove(0);\n+        model.updForceSet().remove(10);\n+        model.updForceSet().remove(30);\n+\n+        // Test that an exception is thrown.\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, sto),\n+                StatesTrajectory::ExtraColumnsInStatesStorage\n+                );\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, sto,\n+                    true, false),\n+                StatesTrajectory::ExtraColumnsInStatesStorage\n+                );\n+        SimTK_TEST_MUST_THROW_EXC(\n+                StatesTrajectory::createFromStatesStorage(model, sto,\n+                    false, false),\n+                StatesTrajectory::ExtraColumnsInStatesStorage\n+                );\n+\n+        // No exception if allowing extra columns, and behavior is\n+        // independent of value for allowMissingColumns.\n+        StatesTrajectory::createFromStatesStorage(model, sto, true, true);\n+        StatesTrajectory::createFromStatesStorage(model, sto, false, true);\n+    }\n+}\n+\n+void testFromStatesStorageUniqueColumnLabels() {\n+\n+    Model model("gait2354_simbody.osim");\n+    Storage sto(statesStoFname);\n+    \n+    // Edit column labels so that they are not unique.\n+    auto labels = sto.getColumnLabels();\n+    labels[10] = labels[7];\n+    sto.setColumnLabels(labels); \n+   \n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto),\n+            StatesTrajectory::NonUniqueColumnsInStatesStorage);\n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto, true, true),\n+            StatesTrajectory::NonUniqueColumnsInStatesStorage);\n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto, true, false),\n+            StatesTrajectory::NonUniqueColumnsInStatesStorage);\n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto, false, true),\n+            StatesTrajectory::NonUniqueColumnsInStatesStorage);\n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto, false, false),\n+            StatesTrajectory::NonUniqueColumnsInStatesStorage);\n+\n+    // TODO unique even considering old and new formats for state variable\n+    // names (/value and /speed) in the same file.\n+}\n+\n+void testFromStatesStoragePre40CorrectStates() {\n+    // This test is very similar to testFromStatesStorageGivesCorrectStates\n+    // TODO could avoid the duplicate function since getStateIndex handles\n+    // pre-4.0 names.\n+\n+    // Read in trajectory.\n+    // -------------------\n+    Model model("gait2354_simbody.osim");\n+\n+    Storage sto(pre40StoFname);\n+    // So the test doesn\'t take so long.\n+    sto.resampleLinear(0.01);\n+    auto states = StatesTrajectory::createFromStatesStorage(model, sto);\n+\n+    model.initSystem();\n+\n+    // Test that the states are correct.\n+    // ---------------------------------\n+    int itime = 0;\n+    double currTime;\n+    for (const auto& state : states) {\n+        // Time.\n+        sto.getTime(itime, currTime);\n+        SimTK_TEST_EQ(currTime, state.getTime());\n+\n+        // Multibody states.\n+        for (int ic = 0; ic < model.getCoordinateSet().getSize(); ++ic) {\n+            const auto& coord = model.getCoordinateSet().get(ic);\n+            auto coordName = coord.getName();\n+\n+            // Coordinate.\n+            SimTK_TEST_EQ(getStorageEntry(sto, itime, coordName),\n+                    coord.getValue(state));\n+\n+            // Speed.\n+            SimTK_TEST_EQ(getStorageEntry(sto, itime, coordName + "_u"),\n+                    coord.getSpeedValue(state));\n+        }\n+\n+        // Muscle states.\n+        for (int im = 0; im < model.getMuscles().getSize(); ++im) {\n+            const auto& muscle = model.getMuscles().get(im);\n+            auto muscleName = muscle.getName();\n+\n+            // Activation.\n+            // TODO Simply accessing these state variables requires realizing\n+            // to Velocity; I think this is a bug.\n+            model.getMultibodySystem().realize(state, SimTK::Stage::Velocity);\n+            SimTK_TEST_EQ(\n+                    getStorageEntry(sto, itime, muscleName + ".activation"),\n+                    muscle.getActivation(state));\n+\n+            // Fiber length.\n+            SimTK_TEST_EQ(\n+                    getStorageEntry(sto, itime, muscleName + ".fiber_length"), \n+                    muscle.getFiberLength(state));\n+\n+            // More complicated computation based on state.\n+            SimTK_TEST(!SimTK::isNaN(muscle.getFiberForce(state)));\n+        }\n+\n+        // More complicated computations based on state.\n+        auto loc = model.getBodySet().get("tibia_r")\n+            .findLocationInAnotherFrame(state,\n+                    SimTK::Vec3(1, 0.5, 0.25),\n+                    model.getGround());\n+        SimTK_TEST(!loc.isNaN());\n+\n+        SimTK_TEST(!model.calcMassCenterVelocity(state).isNaN());\n+        // TODO acceleration-level stuff gives segfault.\n+        // TODO model.getMultibodySystem().realize(state, SimTK::Stage::Acceleration);\n+        // TODO SimTK_TEST(!model.calcMassCenterAcceleration(state).isNaN());\n+\n+        itime++;\n+    }\n+}\n+\n+void testFromStatesStorageAllRowsHaveSameLength() {\n+    // Missing data in individual rows leads to an incorrect StatesTrajectory\n+    // and could really confuse users.\n+    Model model("gait2354_simbody.osim");\n+    model.initSystem();\n+\n+    const auto stateNames = model.getStateVariableNames();\n+    Storage sto(statesStoFname);\n+    // Append a too-short state vector.\n+    std::vector<double> v(model.getNumStateVariables() - 10, 1.0);\n+    StateVector sv(25.0, model.getNumStateVariables() - 10, v.data());\n+    sto.append(sv);\n+\n+    SimTK_TEST_MUST_THROW_EXC(\n+            StatesTrajectory::createFromStatesStorage(model, sto),\n+            StatesTrajectory::VaryingNumberOfStatesPerRow);\n+}\n+\n+\n+void testCopying() {\n+    Model model("gait2354_simbody.osim");\n+    auto& state = model.initSystem();\n+\n+    StatesTrajectory states;\n+    {\n+        state.setTime(0.5);\n+        states.append(state);\n+        state.setTime(1.3);\n+        states.append(state);\n+        state.setTime(3.5);\n+        states.append(state);\n+    }\n+\n+    {\n+        StatesTrajectory statesCopyConstruct(states);\n+        // Ideally we\'d check for equality (operator==()), but State does not\n+        // have an equality operator.\n+        SimTK_TEST_EQ((int)statesCopyConstruct.getSize(), (int)states.getSize());\n+        for (int i = 0; i < states.getSize(); ++i) {\n+            SimTK_TEST_EQ(statesCopyConstruct[i].getTime(), states[i].getTime());\n+        }\n+    }\n+\n+    {\n+        StatesTrajectory statesCopyAssign;\n+        statesCopyAssign = states;\n+        SimTK_TEST_EQ((int)statesCopyAssign.getSize(), (int)states.getSize());\n+        for (int i = 0; i < states.getSize(); ++i) {\n+            SimTK_TEST_EQ(statesCopyAssign[i].getTime(), states[i].getTime());\n+        }\n+    }\n+}\n+\n+void testAppendTimesAreNonDecreasing() {\n+    Model model("gait2354_simbody.osim");\n+    auto& state = model.initSystem();\n+    state.setTime(1.0);\n+\n+    StatesTrajectory states;\n+    states.append(state);\n+\n+    // Multiple states can have the same time; does not throw an exception:\n+    states.append(state);\n+\n+    state.setTime(0.9999);\n+    SimTK_TEST_MUST_THROW_EXC(states.append(state),\n+            SimTK::Exception::APIArgcheckFailed);\n+}\n+\n+void testBoundsCheck() {\n+    Model model("gait2354_simbody.osim");\n+    const auto& state = model.initSystem();\n+    StatesTrajectory states;\n+    states.append(state);\n+    states.append(state);\n+    states.append(state);\n+    states.append(state);\n+    \n+    #ifdef NDEBUG\n+        // In DEBUG, Visual Studio puts asserts into the index operator.\n+        states[states.getSize() + 100];\n+        states[4];\n+        states[5];\n+    #endif\n+    SimTK_TEST_MUST_THROW_EXC(states.get(4), IndexOutOfRange);\n+    SimTK_TEST_MUST_THROW_EXC(states.get(states.getSize() + 100),\n+            IndexOutOfRange);\n+}\n+\n+void testIntegrityChecks() {\n+    Model arm26("arm26.osim");\n+    const auto& s26 = arm26.initSystem();\n+\n+    Model gait2354("gait2354_simbody.osim");\n+    const auto& s2354 = gait2354.initSystem();\n+    // TODO add models with events, unilateral constraints, etc.\n+\n+    // Times are nondecreasing.\n+    {\n+        StatesTrajectory states;\n+        auto state0(s26);\n+        state0.setTime(0.5);\n+        auto state1(s26);\n+        state1.setTime(0.6);\n+\n+        states.append(state0);\n+        states.append(state1);\n+\n+        SimTK_TEST(states.isConsistent());\n+        SimTK_TEST(states.isNondecreasingInTime());\n+        SimTK_TEST(states.hasIntegrity());\n+\n+        // Users should never do this const cast; it\'s just for the sake of\n+        // the test.\n+        const_cast<SimTK::State*>(&states[1])->setTime(0.2);\n+\n+        SimTK_TEST(states.isConsistent());\n+        SimTK_TEST(!states.isNondecreasingInTime());\n+        SimTK_TEST(!states.hasIntegrity());\n+    }\n+\n+    // Consistency and compatibility with a model.\n+    {\n+        StatesTrajectory states;\n+        // An empty trajectory is consistent.\n+        SimTK_TEST(states.isConsistent());\n+\n+        // A length-1 trajectory is consistent.\n+        states.append(s26);\n+        SimTK_TEST(states.isConsistent());\n+\n+        // This trajectory is compatible with the arm26 model.\n+        SimTK_TEST(states.isCompatibleWith(arm26));\n+\n+        // Not compatible with gait2354 model.\n+        // Ensures a lower-dimensional trajectory can\'t pass for a higher\n+        // dimensional model.\n+        SimTK_TEST(!states.isCompatibleWith(gait2354));\n+\n+        // The checks still work with more than 1 state.\n+        states.append(s26);\n+        states.append(s26);\n+        SimTK_TEST(states.isNondecreasingInTime());\n+        SimTK_TEST(states.isConsistent());\n+        SimTK_TEST(states.hasIntegrity());\n+        SimTK_TEST(states.isCompatibleWith(arm26));\n+        SimTK_TEST(!states.isCompatibleWith(gait2354));\n+    }\n+\n+    {\n+        StatesTrajectory states;\n+        states.append(s2354);\n+\n+        // Reverse of the previous check; to ensure that a larger-dimensional\n+        // trajectory can\'t pass for the smaller dimensional model.\n+        SimTK_TEST(states.isCompatibleWith(gait2354));\n+        SimTK_TEST(!states.isCompatibleWith(arm26));\n+\n+        // Check still works with more than 1 state.\n+        states.append(s2354);\n+        states.append(s2354);\n+        SimTK_TEST(states.isNondecreasingInTime());\n+        SimTK_TEST(states.isConsistent());\n+        SimTK_TEST(states.hasIntegrity());\n+        SimTK_TEST(states.isCompatibleWith(gait2354));\n+        SimTK_TEST(!states.isCompatibleWith(arm26));\n+    }\n+\n+    {\n+        // Cannot append inconsistent states.\n+        StatesTrajectory states;\n+        states.append(s26);\n+        SimTK_TEST_MUST_THROW_EXC(states.append(s2354),\n+                StatesTrajectory::InconsistentState);\n+\n+        // Same check, but swap the models.\n+        StatesTrajectory states2;\n+        states2.append(s2354);\n+        SimTK_TEST_MUST_THROW_EXC(states2.append(s26),\n+                StatesTrajectory::InconsistentState);\n+    }\n+\n+    // TODO Show weakness of the test: two models with the same number of Q\'s, U\'s,\n+    // and Z\'s both pass the check. \n+}\n+\n+\n+int main() {\n+    SimTK_START_TEST("testStatesTrajectory");\n+\n+        // actuators library is not loaded automatically (unless using clang).\n+        #if !defined(__clang__)\n+            LoadOpenSimLibrary("osimActuators");\n+        #endif\n+\n+        // Make sure the states Storage file doesn\'t already exist; we\'ll\n+        // generate it later and we don\'t want to use a stale one by accident.\n+        remove(statesStoFname.c_str());\n+\n+        SimTK_SUBTEST(testPopulateTrajectory);\n+        SimTK_SUBTEST(testFrontBack);\n+        SimTK_SUBTEST(testBoundsCheck);\n+        SimTK_SUBTEST(testIntegrityChecks);\n+        SimTK_SUBTEST(testAppendTimesAreNonDecreasing);\n+        SimTK_SUBTEST(testCopying);\n+\n+        // Test creation of trajectory from astates storage.\n+        // -------------------------------------------------\n+        // Using a pre-4.0 states storage file with old column names.\n+        SimTK_SUBTEST(testFromStatesStoragePre40CorrectStates);\n+        SimTK_SUBTEST1(testFromStatesStorageInconsistentModel, pre40StoFname);\n+\n+        // v4.0 states storage\n+        createStateStorageFile();\n+        SimTK_SUBTEST(testFromStatesStorageGivesCorrectStates);\n+        SimTK_SUBTEST1(testFromStatesStorageInconsistentModel, statesStoFname);\n+        SimTK_SUBTEST(testFromStatesStorageUniqueColumnLabels);\n+        SimTK_SUBTEST(testFromStatesStorageAllRowsHaveSameLength);\n+\n+    SimTK_END_TEST();\n+}\ndiff --git a/OpenSim/Simulation/osimSimulation.h b/OpenSim/Simulation/osimSimulation.h\nindex f9c069942..8321bbb77 100644\n--- a/OpenSim/Simulation/osimSimulation.h\n+++ b/OpenSim/Simulation/osimSimulation.h\n@@ -112,6 +112,7 @@\n #include "SimbodyEngine/SpatialTransform.h"\n \n #include "MomentArmSolver.h"\n+#include "StatesTrajectory.h"\n \n #include "RegisterTypes_osimSimulation.h"   // to expose RegisterTypes_osimSimulation\n \ndiff --git a/Applications/CMC/test/std_subject01_walk1_states.sto b/OpenSim/Tests/shared/std_subject01_walk1_states.sto\nsimilarity index 100%\nrename from Applications/CMC/test/std_subject01_walk1_states.sto\nrename to OpenSim/Tests/shared/std_subject01_walk1_states.sto\ndiff --git a/appveyor.yml b/appveyor.yml\nindex 31e8ac7d4..314becb0b 100644\n--- a/appveyor.yml\n+++ b/appveyor.yml\n@@ -35,10 +35,6 @@ init:\n   - SET OPENSIM_DEPENDENCIES_SOURCE_DIR=%OPENSIM_SOURCE_DIR%\\dependencies\n   - SET OPENSIM_DEPENDENCIES_BUILD_DIR=C:\\projects\\opensim_dependencies_build\n   - SET OPENSIM_DEPENDENCIES_INSTALL_DIR=C:\\projects\\opensim_dependencies_install\n-\n-  # The following line, if uncommented, should allow you to remote-desktop into\n-  # the Appveyor build machine.\n-  # - ps: iex ((new-object net.webclient).DownloadString(\'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1\'))\n   \n nuget:\n   account_feed: true\n@@ -72,8 +68,9 @@ build_script:\n   - cd %OPENSIM_BUILD_DIR%\n   # Configure.\n   - cmake %OPENSIM_SOURCE_DIR% -G"Visual Studio 14 2015 Win64" -DSIMBODY_HOME=C:\\simbody -DOPENSIM_DEPENDENCIES_DIR=%OPENSIM_DEPENDENCIES_INSTALL_DIR% -DCMAKE_INSTALL_PREFIX=%OPENSIM_INSTALL_DIR% -DBUILD_JAVA_WRAPPING=ON -DBUILD_PYTHON_WRAPPING=ON # TODO -DBUILD_SIMM_TRANSLATOR=ON\n+\n   # Build.\n-  - cmake --build . --config Release -- /maxcpucount:4 /verbosity:quiet /p:TreatWarningsAsErrors="true"\n+  - cmake --build . --config Release -- /maxcpucount:4 /verbosity:quiet #/p:TreatWarningsAsErrors="true"\n   \n test_script:\n   ## Run tests.\n@@ -97,3 +94,8 @@ after_test:\n   - IF DEFINED DISTR cd %APPVEYOR_BUILD_FOLDER%\n   - IF DEFINED DISTR nuget pack .opensim-core.nuspec -BasePath %OPENSIM_HOME%\n   - IF DEFINED DISTR appveyor PushArtifact opensim-core.0.0.0.nupkg\n+\n+# The following, if uncommented, should allow you to remote-desktop into\n+# the Appveyor build machine.\n+#on_finish:\n+#  - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString(\'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1\'))\ndiff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt\nindex f6c6978e4..4561acfae 100644\n--- a/dependencies/CMakeLists.txt\n+++ b/dependencies/CMakeLists.txt\n@@ -122,7 +122,7 @@ AddDependency(NAME       BTK\n \n AddDependency(NAME       simbody\n               URL        https://github.com/simbody/simbody.git\n-              TAG        ed67885db8983405e0724e63e62bf8e9316b2493\n+              TAG        b98b6813dd87163a92be779cf4dd684e2f124d13\n               CMAKE_ARGS -DBUILD_EXAMPLES:BOOL=OFF \n                          -DBUILD_TESTING:BOOL=OFF)\n \ndiff --git a/doc/doxyfile_shared.in b/doc/doxyfile_shared.in\nindex 3e4175ca6..b6e42c0a4 100644\n--- a/doc/doxyfile_shared.in\n+++ b/doc/doxyfile_shared.in\n@@ -539,7 +539,7 @@ GENERATE_DEPRECATEDLIST= YES\n # documentation can be controlled using \\showinitializer or \\hideinitializer \n # command in the documentation regardless of this setting.\n \n-MAX_INITIALIZER_LINES  = 30\n+MAX_INITIALIZER_LINES  = 1\n \n # Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n # at the bottom of the documentation of classes and structs. If set to YES the \n@@ -1563,6 +1563,9 @@ EXPAND_AS_DEFINED      = OpenSim_DECLARE_PROPERTY \\\n                          OpenSim_DECLARE_LIST_PROPERTY_ATMOST \\\n                          OpenSim_DECLARE_LIST_PROPERTY_RANGE \\\n                          OpenSim_DECLARE_PROPERTY_HELPER \\\n+                         OpenSim_DECLARE_OUTPUT \\\n+                         OpenSim_DECLARE_OUTPUT_NONMEM \\\n+                         OpenSim_DECLARE_OUTPUT_FOR_STATE_VARIABLE \\\n                          SWIG_DECLARE_EXCEPTION\n \n # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \ndiff --git a/doc/doxygen-layout-developer.xml b/doc/doxygen-layout-developer.xml\nindex 25b98a81b..a97e1e5ec 100644\n--- a/doc/doxygen-layout-developer.xml\n+++ b/doc/doxygen-layout-developer.xml\n@@ -66,7 +66,7 @@\n     <collaborationgraph visible="$COLLABORATION_GRAPH"/>\n     <allmemberslink visible="yes"/>\n     <memberdecl>\n-      <properties title="OpenSim (XML) Properties"/>\n+      <properties title="OpenSim Properties, Outputs"/>\n       <publicmethods title=""/>\n       <publictypes title=""/>\n       <publicslots title=""/>\n@@ -109,7 +109,7 @@\n       <functions title=""/>\n       <related title=""/>\n       <variables title=""/>\n-      <properties title="OpenSim (XML) Property Documentation"/>\n+      <properties title="OpenSim Property, Output Documentation"/>\n       <events title=""/>\n     </memberdef>\n     \ndiff --git a/doc/doxygen-layout-user.xml b/doc/doxygen-layout-user.xml\nindex 180fe5428..8302c7193 100644\n--- a/doc/doxygen-layout-user.xml\n+++ b/doc/doxygen-layout-user.xml\n@@ -66,7 +66,7 @@\n     <collaborationgraph visible="$COLLABORATION_GRAPH"/>\n     <allmemberslink visible="yes"/>\n     <memberdecl>\n-      <properties title="OpenSim (XML) Properties"/>\n+      <properties title="OpenSim Properties, Outputs"/>\n       <publicmethods title=""/>\n     </memberdecl>\n    \n@@ -75,7 +75,7 @@\n       <constructors title=""/>\n       <typedefs title=""/>\n       <functions title=""/>\n-      <properties title="OpenSim (XML) Property Documentation"/>\n+      <properties title="OpenSim Property, Output Documentation"/>\n       <!-- <enums title=""/>\n       \n       \ndiff --git a/doc/doxygen_shared.css b/doc/doxygen_shared.css\nindex fe864b638..bf9e784c5 100644\n--- a/doc/doxygen_shared.css\n+++ b/doc/doxygen_shared.css\n@@ -10,7 +10,7 @@ table {\n }\n \n pre, code {\n-    font-family: monospace;\n+\tfont-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;\n }\n \n p {\n@@ -197,15 +197,16 @@ pre.fragment {\n div.fragment {\n         padding: 4px 6px;\n         margin: 4px 8px 4px 2px;\n-\tbackground-color: #e3e3e3;\n-\tborder: 1px solid #e3e3e3;\n-\tfont-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace !important;\n+\tbackground-color: #f3f3f3;\n+\tborder: 1px solid #f3f3f3;\n }\n \n div.line {\n-\tfont-family: monospace;\n+    /* This is the font used for code blocks (@code). Menlo is on OSX, Consolas\n+     * is on Windows. */\n+\tfont-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;\n     font-size: 11px;\n-    color: #717171;\n+    /* color: #000000; */ /* use default font color for code */\n \tmin-height: 13px; \n \tline-height: 1.0;\n \ttext-wrap: unrestricted;\n', 'commit_subject': "Merge branch 'master' into data_adapter_classes", 'repo_name': 'opensim-org/opensim-core', 'committer': {'name': 'Shrinidhi KL', 'email': 'd95ab70d9f94fe9e94415764048b7c0104d27b27@gmail.com', 'time_sec': '1457659592', 'tz_offset': '-480', 'date': {'seconds': '1457659592'}}, 'commit_tree': '80f4a7cdce7e29c19c93a7176c999a482458577b', 'commit_message': "Merge branch 'master' into data_adapter_classes\n", 'language_name': 'HTML', 'license': 'apache-2.0', 'hunks': '@@ -10,7 +10,7 @@ table {\n }\n \n pre, code {\n-    font-family: monospace;\n+\tfont-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;\n }\n \n p {\n@@ -197,15 +197,16 @@ pre.fragment {\n div.fragment {\n         padding: 4px 6px;\n         margin: 4px 8px 4px 2px;\n-\tbackground-color: #e3e3e3;\n-\tborder: 1px solid #e3e3e3;\n-\tfont-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace !important;\n+\tbackground-color: #f3f3f3;\n+\tborder: 1px solid #f3f3f3;\n }\n \n div.line {\n-\tfont-family: monospace;\n+    /* This is the font used for code blocks (@code). Menlo is on OSX, Consolas\n+     * is on Windows. */\n+\tfont-family: Menlo, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;\n     font-size: 11px;\n-    color: #717171;\n+    /* color: #000000; */ /* use default font color for code */\n \tmin-height: 13px; \n \tline-height: 1.0;\n \ttext-wrap: unrestricted;\n', 'addition_count': 7, 'deletion_count': 6, 'src_file': 'a/doc/doxygen_shared.css', 'tgt_file': 'b/doc/doxygen_shared.css', 'file_extension': '.css', 'before_file': '/* The standard CSS for doxygen 1.8.7 */\n\nbody, table, div, p, dl {\n\tfont-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;\n\tfont-size: 12px;\n}\n\ntable {\n    border-collapse: collapse;\n}\n\npre, code {\n    font-family: monospace;\n}\n\np {\n    margin: 1em 0;\n}\n\ndl {\n    margin-bottom: 1em;\n}\n\ndd {\n    margin: .25em 1em;\n}\n\nul {\n    list-style-type: square;\n}\n\nli {\n    margin: 0;\n    padding: .2em 0;\n}\n\n/* @group Heading Levels */\n\nh1, h2, h3, h4 {\n    font-family: "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;\n    margin: 2em 0 1em 0;\n}\n\n.title {\n\tfont-size: 150%;\n}\n\nh2.groupheader {\n\tfont-size: 150%;\n\tborder-bottom: 1px solid #879ECB;;\n}\n\nh3.groupheader {\n\tfont-size: 100%;\n}\n\nh1, h2, h3, h4, h5, h6 {\n\t-webkit-transition: text-shadow 0.5s linear;\n\t-moz-transition: text-shadow 0.5s linear;\n\t-ms-transition: text-shadow 0.5s linear;\n\t-o-transition: text-shadow 0.5s linear;\n\ttransition: text-shadow 0.5s linear;\n\tmargin-right: 15px;\n}\n\nh1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {\n\ttext-shadow: 0 0 15px cyan;\n}\n\ndt {\n\tfont-weight: bold;\n}\n\ndiv.multicol {\n\t-moz-column-gap: 1em;\n\t-webkit-column-gap: 1em;\n\t-moz-column-count: 3;\n\t-webkit-column-count: 3;\n}\n\np.startli, p.startdd {\n\tmargin-top: 2px;\n}\n\np.starttd {\n\tmargin-top: 0px;\n}\n\np.endli {\n\tmargin-bottom: 0px;\n}\n\np.enddd {\n\tmargin-bottom: 4px;\n}\n\np.endtd {\n\tmargin-bottom: 2px;\n}\n\n/* @end */\n\ncaption {\n\tfont-weight: bold;\n}\n\nspan.legend {\n        font-size: 70%;\n        text-align: center;\n}\n\nh3.version {\n        font-size: 90%;\n        text-align: center;\n}\n\ndiv.qindex, div.navtab{\n\tbackground-color: #EBEFF6;\n\tborder: 1px solid #A3B4D7;\n\ttext-align: center;\n}\n\ndiv.qindex, div.navpath {\n\twidth: 100%;\n\tline-height: 140%;\n}\n\ndiv.navtab {\n\tmargin-right: 15px;\n}\n\n/* @group Link Styling */\n\na {\n\tcolor: #439DE0;\n\tfont-weight: normal;\n\ttext-decoration: none;\n}\n\n.contents a:visited {\n\tcolor: #439DE0;\n}\n\na:hover {\n\ttext-decoration: underline;\n}\n\na.qindex {\n\tfont-weight: bold;\n}\n\na.qindexHL {\n\tfont-weight: bold;\n\tbackground-color: #9CAFD4;\n\tcolor: #ffffff;\n\tborder: 1px double #869DCA;\n}\n\n.contents a.qindexHL:visited {\n        color: #ffffff;\n}\n\na.el {\n\tfont-weight: bold;\n}\n\na.elRef {\n}\n\na.code, a.code:visited, a.line, a.line:visited {\n\tcolor: #439DE0; \n}\n\na.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {\n\tcolor: #439DE0; \n}\n\n/* @end */\n\ndl.el {\n\tmargin-left: -1cm;\n}\n\npre.fragment {\n        border: 1px solid #C4CFE5;\n        background-color: #FBFCFD;\n        padding: 4px 6px;\n        margin: 4px 8px 4px 2px;\n        overflow: auto;\n        word-wrap: break-word;\n        font-size:  9pt;\n        line-height: 125%;\n        font-family: sans-serif;\n        font-size: 105%;\n}\n\ndiv.fragment {\n        padding: 4px 6px;\n        margin: 4px 8px 4px 2px;\n\tbackground-color: #e3e3e3;\n\tborder: 1px solid #e3e3e3;\n\tfont-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace !important;\n}\n\ndiv.line {\n\tfont-family: monospace;\n    font-size: 11px;\n    color: #717171;\n\tmin-height: 13px; \n\tline-height: 1.0;\n\ttext-wrap: unrestricted;\n\twhite-space: -moz-pre-wrap; /* Moz */\n\twhite-space: -pre-wrap;     /* Opera 4-6 */\n\twhite-space: -o-pre-wrap;   /* Opera 7 */\n\twhite-space: pre-wrap;      /* CSS3  */\n\tword-wrap: break-word;      /* IE 5.5+ */\n\ttext-indent: -53px;\n\tpadding-left: 53px;\n\tpadding-bottom: 0px;\n\tmargin: 0px;\n\t-webkit-transition-property: background-color, box-shadow;\n\t-webkit-transition-duration: 0.5s;\n\t-moz-transition-property: background-color, box-shadow;\n\t-moz-transition-duration: 0.5s;\n\t-ms-transition-property: background-color, box-shadow;\n\t-ms-transition-duration: 0.5s;\n\t-o-transition-property: background-color, box-shadow;\n\t-o-transition-duration: 0.5s;\n\ttransition-property: background-color, box-shadow;\n\ttransition-duration: 0.5s;\n}\n\ndiv.line.glow {\n\tbackground-color: cyan;\n\tbox-shadow: 0 0 10px cyan;\n}\n\n\nspan.lineno {\n\tpadding-right: 4px;\n\ttext-align: right;\n\tborder-right: 2px solid #0F0;\n\tbackground-color: #E8E8E8;\n        white-space: pre;\n}\nspan.lineno a {\n\tbackground-color: #D8D8D8;\n}\n\nspan.lineno a:hover {\n\tbackground-color: #C8C8C8;\n}\n\ndiv.ah {\n\tbackground-color: black;\n\tfont-weight: bold;\n\tcolor: #ffffff;\n\tmargin-bottom: 3px;\n\tmargin-top: 3px;\n\tpadding: 0.2em;\n\tborder: solid thin #333;\n\tborder-radius: 0.5em;\n\t-webkit-border-radius: .5em;\n\t-moz-border-radius: .5em;\n\tbox-shadow: 2px 2px 3px #999;\n\t-webkit-box-shadow: 2px 2px 3px #999;\n\t-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;\n\tbackground-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));\n\tbackground-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);\n}\n\ndiv.groupHeader {\n\tmargin-left: 16px;\n\tmargin-top: 12px;\n\tfont-weight: bold;\n}\n\ndiv.groupText {\n\tmargin-left: 16px;\n\tfont-style: italic;\n}\n\nbody {\n\tbackground-color: white;\n\tcolor: black;\n        margin: 0;\n}\n\ndiv.contents {\n\tmargin-top: 10px;\n\tmargin-left: 12px;\n\tmargin-right: 8px;\n}\n\ntd.indexkey {\n\tbackground-color: #EBEFF6;\n\tfont-weight: bold;\n\tborder: 1px solid #C4CFE5;\n\tmargin: 2px 0px 2px 0;\n\tpadding: 2px 10px;\n        white-space: nowrap;\n        vertical-align: top;\n}\n\ntd.indexvalue {\n\tbackground-color: #EBEFF6;\n\tborder: 1px solid #C4CFE5;\n\tpadding: 2px 10px;\n\tmargin: 2px 0px;\n}\n\ntr.memlist {\n\tbackground-color: #EEF1F7;\n}\n\np.formulaDsp {\n\ttext-align: center;\n}\n\nimg.formulaDsp {\n\t\n}\n\nimg.formulaInl {\n\tvertical-align: middle;\n}\n\ndiv.center {\n\ttext-align: center;\n        margin-top: 0px;\n        margin-bottom: 0px;\n        padding: 0px;\n}\n\ndiv.center img {\n\tborder: 0px;\n}\n\naddress.footer {\n\ttext-align: right;\n\tpadding-right: 12px;\n}\n\nimg.footer {\n\tborder: 0px;\n\tvertical-align: middle;\n}\n\n/* @group Code Colorization */\n\nspan.keyword {\n\tcolor: #B30303\n}\n\nspan.keywordtype {\n\tcolor: #ac3646\n}\n\nspan.keywordflow {\n\tcolor: #e08000\n}\n\nspan.comment {\n\tcolor: #2d499d\n}\n\nspan.preprocessor {\n\tcolor: #806020\n}\n\nspan.stringliteral {\n\tcolor: #002080\n}\n\nspan.charliteral {\n\tcolor: #008080\n}\n\nspan.vhdldigit { \n\tcolor: #ff00ff \n}\n\nspan.vhdlchar { \n\tcolor: #000000 \n}\n\nspan.vhdlkeyword { \n\tcolor: #700070 \n}\n\nspan.vhdllogic { \n\tcolor: #ff0000 \n}\n\nblockquote {\n        background-color: #F7F8FB;\n        border-left: 2px solid #9CAFD4;\n        margin: 0 24px 0 4px;\n        padding: 0 12px 0 16px;\n}\n\n/* @end */\n\n/*\n.search {\n\tcolor: #003399;\n\tfont-weight: bold;\n}\n\nform.search {\n\tmargin-bottom: 0px;\n\tmargin-top: 0px;\n}\n\ninput.search {\n\tfont-size: 75%;\n\tcolor: #000080;\n\tfont-weight: normal;\n\tbackground-color: #e8eef2;\n}\n*/\n\ntd.tiny {\n\tfont-size: 75%;\n}\n\n.dirtab {\n\tpadding: 4px;\n\tborder-collapse: collapse;\n\tborder: 1px solid #A3B4D7;\n}\n\nth.dirtab {\n\tbackground: #EBEFF6;\n\tfont-weight: bold;\n}\n\nhr {\n\theight: 0px;\n\tborder: none;\n\tborder-top: 1px solid #4A6AAA;\n}\n\nhr.footer {\n\theight: 1px;\n}\n\n/* @group Member Descriptions */\n\ntable.memberdecls {\n\tborder-spacing: 0px;\n\tpadding: 0px;\n}\n\n.memberdecls td, .fieldtable tr {\n\t-webkit-transition-property: background-color, box-shadow;\n\t-webkit-transition-duration: 0.5s;\n\t-moz-transition-property: background-color, box-shadow;\n\t-moz-transition-duration: 0.5s;\n\t-ms-transition-property: background-color, box-shadow;\n\t-ms-transition-duration: 0.5s;\n\t-o-transition-property: background-color, box-shadow;\n\t-o-transition-duration: 0.5s;\n\ttransition-property: background-color, box-shadow;\n\ttransition-duration: 0.5s;\n}\n\n.memberdecls td.glow, .fieldtable tr.glow {\n\tbackground-color: cyan;\n\tbox-shadow: 0 0 15px cyan;\n}\n\n.mdescLeft, .mdescRight,\n.memItemLeft, .memItemRight,\n.memTemplItemLeft, .memTemplItemRight, .memTemplParams {\n\tbackground-color: #F9FAFC;\n\tborder: none;\n\tmargin: 4px;\n\tpadding: 1px 0 0 8px;\n}\n\n.mdescLeft, .mdescRight {\n\tpadding: 0px 8px 4px 8px;\n\tcolor: #555;\n}\n\n.memSeparator {\n        border-bottom: 1px solid #DEE4F0;\n        line-height: 1px;\n        margin: 0px;\n        padding: 0px;\n}\n\n.memItemLeft, .memTemplItemLeft {\n        white-space: nowrap;\n}\n\n.memItemRight {\n\twidth: 100%;\n}\n\n.memTemplParams {\n\tcolor: #439DE0;\n        white-space: nowrap;\n\tfont-size: 80%;\n}\n\n/* @end */\n\n/* @group Member Details */\n\n/* Styles for detailed member documentation */\n\n.memtemplate {\n\tfont-size: 80%;\n\tcolor: #439DE0;\n\tfont-weight: normal;\n\tmargin-left: 9px;\n}\n\n.memnav {\n\tbackground-color: #EBEFF6;\n\tborder: 1px solid #A3B4D7;\n\ttext-align: center;\n\tmargin: 2px;\n\tmargin-right: 15px;\n\tpadding: 2px;\n}\n\n.mempage {\n\twidth: 100%;\n}\n\n.memitem {\n\tpadding: 0;\n\tmargin-bottom: 10px;\n\tmargin-right: 5px;\n        -webkit-transition: box-shadow 0.5s linear;\n        -moz-transition: box-shadow 0.5s linear;\n        -ms-transition: box-shadow 0.5s linear;\n        -o-transition: box-shadow 0.5s linear;\n        transition: box-shadow 0.5s linear;\n        display: table !important;\n        width: 100%;\n}\n\n.memitem.glow {\n         box-shadow: 0 0 15px cyan;\n}\n\n.memname {\n        font-weight: bold;\n        margin-left: 6px;\n}\n\n.memname td {\n\tvertical-align: bottom;\n}\n\n.memproto, dl.reflist dt {\n        border-top: 1px solid #A8B8D9;\n        border-left: 1px solid #A8B8D9;\n        border-right: 1px solid #A8B8D9;\n        padding: 6px 0px 6px 0px;\n        color: #253555;\n        font-weight: bold;\n        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n        background-repeat:repeat-x;\n        background-color: #E2E2E2;\n        /* opera specific markup */\n        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        border-top-right-radius: 4px;\n        border-top-left-radius: 4px;\n        /* firefox specific markup */\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;\n        -moz-border-radius-topright: 4px;\n        -moz-border-radius-topleft: 4px;\n        /* webkit specific markup */\n        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        -webkit-border-top-right-radius: 4px;\n        -webkit-border-top-left-radius: 4px;\n\n}\n\n.memdoc, dl.reflist dd {\n        border-bottom: 1px solid #A8B8D9;      \n        border-left: 1px solid #A8B8D9;      \n        border-right: 1px solid #A8B8D9; \n        padding: 6px 10px 2px 10px;\n        background-color: #FBFCFD;\n        border-top-width: 0;\n        background-image:url(\'nav_g.png\');\n        background-repeat:repeat-x;\n        background-color: #FFFFFF;\n        /* opera specific markup */\n        border-bottom-left-radius: 4px;\n        border-bottom-right-radius: 4px;\n        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n        /* firefox specific markup */\n        -moz-border-radius-bottomleft: 4px;\n        -moz-border-radius-bottomright: 4px;\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;\n        /* webkit specific markup */\n        -webkit-border-bottom-left-radius: 4px;\n        -webkit-border-bottom-right-radius: 4px;\n        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);\n}\n\ndl.reflist dt {\n        padding: 5px;\n}\n\ndl.reflist dd {\n        margin: 0px 0px 10px 0px;\n        padding: 5px;\n}\n\n.paramkey {\n\ttext-align: right;\n}\n\n.paramtype {\n\twhite-space: nowrap;\n}\n\n.paramname {\n\tcolor: #602020;\n\twhite-space: nowrap;\n}\n.paramname em {\n\tfont-style: normal;\n}\n.paramname code {\n        line-height: 14px;\n}\n\n.params, .retval, .exception, .tparams {\n        margin-left: 0px;\n        padding-left: 0px;\n}       \n\n.params .paramname, .retval .paramname {\n        font-weight: bold;\n        vertical-align: top;\n}\n        \n.params .paramtype {\n        font-style: italic;\n        vertical-align: top;\n}       \n        \n.params .paramdir {\n        font-family: monospace;\n        vertical-align: top;\n}\n\ntable.mlabels {\n\tborder-spacing: 0px;\n}\n\ntd.mlabels-left {\n\twidth: 100%;\n\tpadding: 0px;\n}\n\ntd.mlabels-right {\n\tvertical-align: bottom;\n\tpadding: 0px;\n\twhite-space: nowrap;\n}\n\nspan.mlabels {\n        margin-left: 8px;\n}\n\nspan.mlabel {\n        background-color: #728DC1;\n        border-top:1px solid #5373B4;\n        border-left:1px solid #5373B4;\n        border-right:1px solid #C4CFE5;\n        border-bottom:1px solid #C4CFE5;\n\ttext-shadow: none;\n\tcolor: white;\n\tmargin-right: 4px;\n\tpadding: 2px 3px;\n\tborder-radius: 3px;\n\tfont-size: 7pt;\n\twhite-space: nowrap;\n\tvertical-align: middle;\n}\n\n\n\n/* @end */\n\n/* these are for tree view inside a (index) page */\n\ndiv.directory {\n        margin: 10px 0px;\n        border-top: 1px solid #9CAFD4;\n        border-bottom: 1px solid #9CAFD4;\n        width: 100%;\n}\n\n.directory table {\n        border-collapse:collapse;\n}\n\n.directory td {\n        margin: 0px;\n        padding: 0px;\n\tvertical-align: top;\n}\n\n.directory td.entry {\n        white-space: nowrap;\n        padding-right: 6px;\n\tpadding-top: 3px;\n}\n\n.directory td.entry a {\n        outline:none;\n}\n\n.directory td.entry a img {\n        border: none;\n}\n\n.directory td.desc {\n        width: 100%;\n        padding-left: 6px;\n\tpadding-right: 6px;\n\tpadding-top: 3px;\n\tborder-left: 1px solid rgba(0,0,0,0.05);\n}\n\n.directory tr.even {\n\tpadding-left: 6px;\n\tbackground-color: #F7F8FB;\n}\n\n.directory img {\n\tvertical-align: -30%;\n}\n\n.directory .levels {\n        white-space: nowrap;\n        width: 100%;\n        text-align: right;\n        font-size: 9pt;\n}\n\n.directory .levels span {\n        cursor: pointer;\n        padding-left: 2px;\n        padding-right: 2px;\n\tcolor: #439DE0;\n}\n\n.arrow {\n    color: #9CAFD4;\n    -webkit-user-select: none;\n    -khtml-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n    cursor: pointer;\n    font-size: 80%;\n    display: inline-block;\n    width: 16px;\n    height: 22px;\n}\n\n.icon {\n    font-family: Arial, Helvetica;\n    font-weight: bold;\n    font-size: 12px;\n    height: 14px;\n    width: 16px;\n    display: inline-block;\n    background-color: #728DC1;\n    color: white;\n    text-align: center;\n    border-radius: 4px;\n    margin-left: 2px;\n    margin-right: 2px;\n}\n\n.icona {\n    width: 24px;\n    height: 22px;\n    display: inline-block;\n}\n\n.iconfopen {\n    width: 24px;\n    height: 18px;\n    margin-bottom: 4px;\n    background-image:url(\'ftv2folderopen.png\');\n    background-position: 0px -4px;\n    background-repeat: repeat-y;\n    vertical-align:top;\n    display: inline-block;\n}\n\n.iconfclosed {\n    width: 24px;\n    height: 18px;\n    margin-bottom: 4px;\n    background-image:url(\'ftv2folderclosed.png\');\n    background-position: 0px -4px;\n    background-repeat: repeat-y;\n    vertical-align:top;\n    display: inline-block;\n}\n\n.icondoc {\n    width: 24px;\n    height: 18px;\n    margin-bottom: 4px;\n    background-image:url(\'ftv2doc.png\');\n    background-position: 0px -4px;\n    background-repeat: repeat-y;\n    vertical-align:top;\n    display: inline-block;\n}\n\ntable.directory {\n    font: 400 12px Roboto,sans-serif;\n}\n\n/* @end */\n\ndiv.dynheader {\n        margin-top: 8px;\n\t-webkit-touch-callout: none;\n\t-webkit-user-select: none;\n\t-khtml-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n\naddress {\n\tfont-style: normal;\n\tcolor: #2A3D61;\n}\n\ntable.doxtable {\n\tborder-collapse:collapse;\n        margin-top: 4px;\n        margin-bottom: 4px;\n}\n\ntable.doxtable td, table.doxtable th {\n\tborder: 1px solid #2D4068;\n\tpadding: 3px 7px 2px;\n}\n\ntable.doxtable th {\n\tbackground-color: #374F7F;\n\tcolor: #FFFFFF;\n\tfont-size: 110%;\n\tpadding-bottom: 4px;\n\tpadding-top: 5px;\n}\n\ntable.fieldtable {\n        /*width: 100%;*/\n        margin-bottom: 10px;\n        border: 1px solid #A8B8D9;\n        border-spacing: 0px;\n        -moz-border-radius: 4px;\n        -webkit-border-radius: 4px;\n        border-radius: 4px;\n        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;\n        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\n        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);\n}\n\n.fieldtable td, .fieldtable th {\n        padding: 3px 7px 2px;\n}\n\n.fieldtable td.fieldtype, .fieldtable td.fieldname {\n        white-space: nowrap;\n        border-right: 1px solid #A8B8D9;\n        border-bottom: 1px solid #A8B8D9;\n        vertical-align: top;\n}\n\n.fieldtable td.fieldname {\n        padding-top: 3px;\n}\n\n.fieldtable td.fielddoc {\n        border-bottom: 1px solid #A8B8D9;\n        /*width: 100%;*/\n}\n\n.fieldtable td.fielddoc p:first-child {\n        margin-top: 0px;\n}       \n        \n.fieldtable td.fielddoc p:last-child {\n        margin-bottom: 2px;\n}\n\n.fieldtable tr:last-child td {\n        border-bottom: none;\n}\n\n.fieldtable th {\n        background-image:url(\'nav_f.png\');\n        background-repeat:repeat-x;\n        background-color: #E2E8F2;\n        font-size: 90%;\n        color: #253555;\n        padding-bottom: 4px;\n        padding-top: 5px;\n        text-align:left;\n        -moz-border-radius-topleft: 4px;\n        -moz-border-radius-topright: 4px;\n        -webkit-border-top-left-radius: 4px;\n        -webkit-border-top-right-radius: 4px;\n        border-top-left-radius: 4px;\n        border-top-right-radius: 4px;\n        border-bottom: 1px solid #A8B8D9;\n}\n/* ADDITIONS */\n.tabs, .tabs2, .tabs3 {\n    background: #F6F6F6 !important;\n    border-bottom: 1px solid #eaeaea;\n    width: 100%;\n    z-index: 101;\n    font-size: 110%;\n}\n\n.tabs a, .tabs2 a{\n    text-align: center;\n}\n\n.tabs2 {\n    font-size: 90%;\n}\n\n.tablist {\n    margin: 0;\n    padding: 0;\n    display: table;\n}\n\n.tablist li {\n    float: left;\n    display: table-cell;\n    line-height: 36px;\n    list-style: none;\n    background: inherit;\n    padding: 0;\n}\n\n.tablist a {\n    display: block;\n    padding: 0 20px;\n    font-weight: bold;\n    text-decoration: none;\n    outline: none;\n    background: none;\n    color: #444;\n    border-right: 1px solid #eaeaea;\n}\n\n.tablist a:hover {\n    background: inherit;\n    text-decoration: none;\n    text-shadow: none;\n    color: gray;\n}\n\n.tabs3 {\n    font-size: 100%;\n    max-height: 20px;\n    line-height: 0px;\n}\n\n.tabs3 li {\n    padding: 0px;\n    margin: 0px;\n    line-height: 20px;\n}\n\n.tabs3 .tablist a {\n    padding: 0 10px;\n    height: 20px;\n    padding-top: 0px;\n    margin-top: 0px;\n}\n\n.tablist li.current a {\n    background: #ddd;\n    color: #444;\n    text-shadow: none;\n}\n\n.tabs2 li{\n     padding: 0px;\n    margin: 0px;\n    line-height: 30px;\n}\n\n\n#nav-tree .children_ul {\n    margin:0;\n    padding:1px;\n}\n\n#nav-tree ul {\n    list-style:none outside none;\n    margin:0px;\n    padding: 5px;\n}\n\n#nav-tree li {\n    white-space:nowrap;\n    margin:0px;\n    padding-top: 1px;\n}\n\n#nav-tree .plus {\n    margin:0px;\n}\n\n#nav-tree .selected {\n    background-color: #9CAFD4 !important;\n    border-top: none;\n    background-image: none;\n}\n\n#nav-tree img {\n  margin:0px;\n  padding:0px;\n  border:0px;\n  -webkit-filter: grayscale(1);\n  width: 8px;\n  height: 11px;\n  margin-top: -4px;\n}\n\n#nav-tree .selected img {\n     -webkit-filter: grayscale(0);\n}\n\n#nav-tree a {\n  text-decoration:none;\n  padding:0px;\n  margin:0px;\n  outline:none;\n  color: #333;\n}\n\n#nav-tree .label {\n  margin:0px;\n  padding:0px;\n}\n\n#nav-tree .label a {\n  padding:2px;\n}\n\n#nav-tree .selected a {\n  text-decoration:none;\n  padding:2px;\n  margin:0px;\n  color: white;\n  text-shadow: none;\n  font-weight: bold;\n}\n\n#nav-tree .children_ul {\n  margin:0px;\n  padding:0px;\n}\n\n#nav-tree .item {\n  margin:0px;\n  padding:0px;\n  height:16px;\n}\n\n#nav-tree {\n  padding: 0px 0px;\n  background: white;\n  font-size:14px;\n  overflow:auto;\n  padding-right: 0px !important;\n  margin-right: -5px !important;\n}\n\n.ui-resizable .ui-resizable-handle {\n  display:block;\n  background-image: none !important;\n}\n\n.ui-resizable-e {\n  background: #eaeaea !important;\n  cursor:e-resize;\n  height:100%;\n  right:0;\n  top:0;\n  width: 1px !important;\n}\n\n.ui-resizable-handle {\n  display:none;\n  font-size:0.1px;\n  position:absolute;\n  z-index:1;\n}\n\n.tabsearch {\n\ttop: 0px;\n\tleft: 10px;\n\theight: 36px;\n\tbackground-color: red;\n\tz-index: 101;\n\toverflow: hidden;\n\tfont-size: 13px;\n}\n\n.navpath ul\n{\n\tfont-size: 9px;\n\tbackground-color: #b7b7b7;\n\tbackground: -webkit-gradient(linear,left top,left bottom,from(whitesmoke),to(#CCC));\n\tbackground-repeat:repeat-x;\n\tbackground-position: 0 0px;\n\theight:30px;\n\tline-height:30px;\n\tcolor:#8AA0CC;\n\tborder:solid 1px #C2CDE4;\n\toverflow:hidden;\n\tmargin:0px;\n\tpadding:0px;\n}\n\n.navpath li\n{\n\tlist-style-type:none;\n\tfloat:left;\n\tpadding-left:10px;\n\tpadding-right:15px;\n\tbackground-image:url(\'bc_s.png\');\n\tbackground-repeat:no-repeat;\n\tbackground-position:right;\n\tcolor:#364D7C;\n}\n\n.navpath li.navelem a\n{\n\theight:32px;\n\tdisplay:block;\n\ttext-decoration: none;\n\toutline: none;\n\tcolor: #283A5D;\n\tfont-family: \'Lucida Grande\',Geneva,Helvetica,Arial,sans-serif;\n\ttext-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n\ttext-decoration: none;        \n}\n\n.navpath li.navelem a:hover\n{\n\tcolor:#6884BD;\n}\n\n.navpath li.footer\n{\n        list-style-type:none;\n        float:right;\n        padding-left:10px;\n        padding-right:15px;\n        background-image:none;\n        background-repeat:no-repeat;\n        background-position:right;\n        color:#364D7C;\n        font-size: 8pt;\n}\n\n\ndiv.summary\n{\n\tfloat: right;\n\tfont-size: 8pt;\n\tpadding-right: 5px;\n\twidth: 50%;\n\ttext-align: right;\n}       \n\ndiv.summary a\n{\n\twhite-space: nowrap;\n}\n\ndiv.ingroups\n{\n\tfont-size: 8pt;\n\twidth: 50%;\n\ttext-align: left;\n}\n\ndiv.ingroups a\n{\n\twhite-space: nowrap;\n}\n\ndiv.header\n{\n        background-image:url(\'nav_h.png\');\n        background-repeat:repeat-x;\n\tbackground-color: #F9FAFC;\n\tmargin:  0px;\n\tborder-bottom: 1px solid #C4CFE5;\n}\n\ndiv.headertitle\n{\n\tpadding: 5px 5px 5px 10px;\n}\n\ndl\n{\n        padding: 0 0 0 10px;\n}\n\n/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */\ndl.section\n{\n\tmargin-left: 0px;\n\tpadding-left: 0px;\n}\n\ndl.note\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #D0C000;\n}\n\ndl.warning, dl.attention\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #FF0000;\n}\n\ndl.pre, dl.post, dl.invariant\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #00D000;\n}\n\ndl.deprecated\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #505050;\n}\n\ndl.todo\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #00C0E0;\n}\n\ndl.test\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #3030E0;\n}\n\ndl.bug\n{\n        margin-left:-7px;\n        padding-left: 3px;\n        border-left:4px solid;\n        border-color: #C08050;\n}\n\ndl.section dd {\n\tmargin-bottom: 6px;\n}\n\n\n#projectlogo\n{\n\ttext-align: center;\n\tvertical-align: bottom;\n\tborder-collapse: separate;\n}\n \n#projectlogo img\n{ \n\tborder: 0px none;\n}\n \n#projectname\n{\n\tfont: 300% Tahoma, Arial,sans-serif;\n\tmargin: 0px;\n\tpadding: 2px 0px;\n}\n    \n#projectbrief\n{\n\tfont: 120% Tahoma, Arial,sans-serif;\n\tmargin: 0px;\n\tpadding: 0px;\n}\n\n#projectnumber\n{\n\tfont: 75% Tahoma, Arial,sans-serif;\n\tmargin: 0px;\n\tpadding: 0px;\n}\n\n.image\n{\n        text-align: center;\n}\n\n.dotgraph\n{\n        text-align: center;\n}\n\n.mscgraph\n{\n        text-align: center;\n}\n\n.diagraph\n{\n        text-align: center;\n}\n\n.caption\n{\n\tfont-weight: bold;\n}\n\ndiv.zoom\n{\n\tborder: 1px solid #90A5CE;\n}\n\ndl.citelist {\n        margin-bottom:50px;\n}\n\ndl.citelist dt {\n        color:#334975;\n        float:left;\n        font-weight:bold;\n        margin-right:10px;\n        padding:5px;\n}\n\ndl.citelist dd {\n        margin:2px 0;\n        padding:5px 0;\n}\n\ndiv.toc {\n        padding: 14px 25px;\n        background-color: #F4F6FA;\n        border: 1px solid #D8DFEE;\n        border-radius: 7px 7px 7px 7px;\n        float: right;\n        height: auto;\n        margin: 0 20px 10px 10px;\n        width: 200px;\n}\n\ndiv.toc li {\n        background: url("bdwn.png") no-repeat scroll 0 5px transparent;\n        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;\n        margin-top: 5px;\n        padding-left: 10px;\n        padding-top: 2px;\n}\n\ndiv.toc h3 {\n        font: bold 12px/1.2 Arial,FreeSans,sans-serif;\n\tcolor: #439DE0;\n        border-bottom: 0 none;\n        margin: 0;\n}\n\ndiv.toc ul {\n        list-style: none outside none;\n        border: medium none;\n        padding: 0px;\n}       \n\ndiv.toc li.level1 {\n        margin-left: 0px;\n}\n\ndiv.toc li.level2 {\n        margin-left: 15px;\n}\n\ndiv.toc li.level3 {\n        margin-left: 30px;\n}\n\ndiv.toc li.level4 {\n        margin-left: 45px;\n}\n\n.inherit_header {\n        font-weight: bold;\n        color: gray;\n        cursor: pointer;\n\t-webkit-touch-callout: none;\n\t-webkit-user-select: none;\n\t-khtml-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n\n.inherit_header td {\n        padding: 6px 0px 2px 5px;\n}\n\n.inherit {\n        display: none;\n}\n\ntr.heading h2 {\n        margin-top: 12px;\n        margin-bottom: 4px;\n}\n\n/* tooltip related style info */\n\n.ttc {\n        position: absolute;\n        display: none;\n}\n\n#powerTip {\n\tcursor: default;\n\twhite-space: nowrap;\n\tbackground-color: white;\n\tborder: 1px solid gray;\n\tborder-radius: 4px 4px 4px 4px;\n\tbox-shadow: 1px 1px 7px gray;\n\tdisplay: none;\n\tfont-size: smaller;\n\tmax-width: 80%;\n\topacity: 0.9;\n\tpadding: 1ex 1em 1em;\n\tposition: absolute;\n\tz-index: 2147483647;\n}\n\n#powerTip div.ttdoc {\n        color: grey;\n\tfont-style: italic;\n}\n\n#powerTip div.ttname a {\n        font-weight: bold;\n}\n\n#powerTip div.ttname {\n        font-weight: bold;\n}\n\n#powerTip div.ttdeci {\n        color: #006318;\n}\n\n#powerTip div {\n        margin: 0px;\n        padding: 0px;\n        font: 12px/16px Roboto,sans-serif;\n}\n\n#powerTip:before, #powerTip:after {\n\tcontent: "";\n\tposition: absolute;\n\tmargin: 0px;\n}\n\n#powerTip.n:after,  #powerTip.n:before,\n#powerTip.s:after,  #powerTip.s:before,\n#powerTip.w:after,  #powerTip.w:before,\n#powerTip.e:after,  #powerTip.e:before,\n#powerTip.ne:after, #powerTip.ne:before,\n#powerTip.se:after, #powerTip.se:before,\n#powerTip.nw:after, #powerTip.nw:before,\n#powerTip.sw:after, #powerTip.sw:before {\n\tborder: solid transparent;\n\tcontent: " ";\n\theight: 0;\n\twidth: 0;\n\tposition: absolute;\n}\n\n#powerTip.n:after,  #powerTip.s:after,\n#powerTip.w:after,  #powerTip.e:after,\n#powerTip.nw:after, #powerTip.ne:after,\n#powerTip.sw:after, #powerTip.se:after {\n\tborder-color: rgba(255, 255, 255, 0);\n}\n\n#powerTip.n:before,  #powerTip.s:before,\n#powerTip.w:before,  #powerTip.e:before,\n#powerTip.nw:before, #powerTip.ne:before,\n#powerTip.sw:before, #powerTip.se:before {\n\tborder-color: rgba(128, 128, 128, 0);\n}\n\n#powerTip.n:after,  #powerTip.n:before,\n#powerTip.ne:after, #powerTip.ne:before,\n#powerTip.nw:after, #powerTip.nw:before {\n\ttop: 100%;\n}\n\n#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {\n\tborder-top-color: #ffffff;\n\tborder-width: 10px;\n\tmargin: 0px -10px;\n}\n#powerTip.n:before {\n\tborder-top-color: #808080;\n\tborder-width: 11px;\n\tmargin: 0px -11px;\n}\n#powerTip.n:after, #powerTip.n:before {\n\tleft: 50%;\n}\n\n#powerTip.nw:after, #powerTip.nw:before {\n\tright: 14px;\n}\n\n#powerTip.ne:after, #powerTip.ne:before {\n\tleft: 14px;\n}\n\n#powerTip.s:after,  #powerTip.s:before,\n#powerTip.se:after, #powerTip.se:before,\n#powerTip.sw:after, #powerTip.sw:before {\n\tbottom: 100%;\n}\n\n#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {\n\tborder-bottom-color: #ffffff;\n\tborder-width: 10px;\n\tmargin: 0px -10px;\n}\n\n#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {\n\tborder-bottom-color: #808080;\n\tborder-width: 11px;\n\tmargin: 0px -11px;\n}\n\n#powerTip.s:after, #powerTip.s:before {\n\tleft: 50%;\n}\n\n#powerTip.sw:after, #powerTip.sw:before {\n\tright: 14px;\n}\n\n#powerTip.se:after, #powerTip.se:before {\n\tleft: 14px;\n}\n\n#powerTip.e:after, #powerTip.e:before {\n\tleft: 100%;\n}\n#powerTip.e:after {\n\tborder-left-color: #ffffff;\n\tborder-width: 10px;\n\ttop: 50%;\n\tmargin-top: -10px;\n}\n#powerTip.e:before {\n\tborder-left-color: #808080;\n\tborder-width: 11px;\n\ttop: 50%;\n\tmargin-top: -11px;\n}\n\n#powerTip.w:after, #powerTip.w:before {\n\tright: 100%;\n}\n#powerTip.w:after {\n\tborder-right-color: #ffffff;\n\tborder-width: 10px;\n\ttop: 50%;\n\tmargin-top: -10px;\n}\n#powerTip.w:before {\n\tborder-right-color: #808080;\n\tborder-width: 11px;\n\ttop: 50%;\n\tmargin-top: -11px;\n}\n\n@media print\n{\n  #top { display: none; }\n  #side-nav { display: none; }\n  #nav-path { display: none; }\n  body { overflow:visible; }\n  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }\n  .summary { display: none; }\n  .memitem { page-break-inside: avoid; }\n  #doc-content\n  {\n    margin-left:0 !important;\n    height:auto !important;\n    width:auto !important;\n    overflow:inherit;\n    display:inline;\n  }\n}\n\n', 'message': "Merge branch 'master' into data_adapter_classes\n", 'author_name': 'Shrinidhi KL', 'lang': 'css'}