[TFUI] Test Driving GUIs that contain Tables

"Daniel Wellman" <wellman-pD6z9c7pN/[email protected]> Sat, 28 Jul 2007 20:59:14 -0400
Newsgroups gmane.comp.programming.test-first-user-interfaces
Message-ID <[email protected]>
--2Uwxe7lHjejHzx47VnxDCuFYKzESbVt0bVTaG-D
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Greetings,

I'm interested to learn how folks approach TDDing views which contain
tables.  I've read about using various styles of presenters (Supervising
Controller, Passive View, etc.) and was interested to hear what experiences
folks have had.  I've just been reading Jeremy D. Miller's series on TDDing
GUIs
<http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx>and
they were quite good.

In my particular case, I'm using the Google Web Toolkit (GWT) and need to
display a table of data.  The interesting bits are:
- The table has a variable number of columns based on the data set being
displayed
- The table only shows certain columns (and variations of widgets) based
upon the user's permissions
- Each row contains widgets which may have different states (for example,
one cell might contain a combobox with a button, or might be a string with
no widgets)


So far I've started to try out a Passive View approach, where the controller
tells the view to add each cell individually.  This is fairly verbose, and
one way requires the controller to tell the view the specific row and
column, e.g.

...
view.addLabelWithTextAt(5, 10, "Hello");  // row 5, column 10
view.addTitleSelectBoxAt(5, 11, listOfStringTitles, indexOfSelectedItem);
view.setReadOnlyList(5, 12, anotherListOfOptions);
...

This feels fairly chatty, and sometimes slightly awkward --- e.g. creating a
Select Box with a list of all valid options and the index/value selected in
one call.  The advantage here is that it's very explicit in the view and I
could test this behavior.

Then, the view calls back to the controller with an index of the row that
received an event, so the controller can find the corresponding model in its
list.  e.g. in the view

checkbox.addChangeListener() {
...
  controller.titleChanged(11);  // the Title Select Box widget is created
with a row # index
..
}



I know an alternative to Passive View would be a Supervising Controller,
where the View could take the set of model objects and explicitly map and
create all the columns needed.  e.g. in the controller:

view.setPeopleList(people);

Since there are requirements that the table column length varies based upon
the data set, and some controls vary based upon permissions, this seems to
encode a lot of responsibility in the view... and that responsibility will
be trickier to test.  (However, GWT does provide a test case which lets you
instantiate widgets in isolation, so perhaps this is another way to test.)


Can anyone comment on their experiences with this kind of work?

Thanks,

Dan


[Non-text portions of this message have been removed]


--2Uwxe7lHjejHzx47VnxDCuFYKzESbVt0bVTaG-D
Content-Type: text/html; charset=US-ASCII
Content-Transfer-Encoding: 7bit


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>

<!-- Network content -->


<body style="background-color: #ffffff;">

<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="width:655px; position:relative;">
  <div id="ygrp-msg" style="width: 490px; padding: 0 15px 0 0; float:left;  z-index:1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->

    <div id="ygrp-text">
            <p>Greetings,<br>
<br>
I'm interested to learn how folks approach TDDing views which contain<br>
tables.  I've read about using various styles of presenters (Supervising<br>
Controller, Passive View, etc.) and was interested to hear what experiences<br>
folks have had.  I've just been reading Jeremy D. Miller's series on TDDing<br>
GUIs<br>
&lt;<a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx">http://codebetter.<wbr>com/blogs/<wbr>jeremy.miller/<wbr>archive/2007/<wbr>07/25/the-<wbr>build-your-<wbr>own-cab-series-<wbr>table-of-<wbr>contents.<wbr>aspx</a>&gt;and<br>
they were quite good.<br>
<br>
In my particular case, I'm using the Google Web Toolkit (GWT) and need to<br>
display a table of data.  The interesting bits are:<br>
- The table has a variable number of columns based on the data set being<br>
displayed<br>
- The table only shows certain columns (and variations of widgets) based<br>
upon the user's permissions<br>
- Each row contains widgets which may have different states (for example,<br>
one cell might contain a combobox with a button, or might be a string with<br>
no widgets)<br>
<br>
So far I've started to try out a Passive View approach, where the controller<br>
tells the view to add each cell individually.  This is fairly verbose, and<br>
one way requires the controller to tell the view the specific row and<br>
column, e.g.<br>
<br>
...<br>
view.addLabelWithTe<wbr>xtAt(5, 10, &quot;Hello&quot;);  // row 5, column 10<br>
view.addTitleSelect<wbr>BoxAt(5, 11, listOfStringTitles, indexOfSelectedItem<wbr>);<br>
view.setReadOnlyLis<wbr>t(5, 12, anotherListOfOption<wbr>s);<br>
...<br>
<br>
This feels fairly chatty, and sometimes slightly awkward --- e.g. creating a<br>
Select Box with a list of all valid options and the index/value selected in<br>
one call.  The advantage here is that it's very explicit in the view and I<br>
could test this behavior.<br>
<br>
Then, the view calls back to the controller with an index of the row that<br>
received an event, so the controller can find the corresponding model in its<br>
list.  e.g. in the view<br>
<br>
checkbox.addChangeL<wbr>istener() {<br>
...<br>
  controller.titleCha<wbr>nged(11);  // the Title Select Box widget is created<br>
with a row # index<br>
..<br>
}<br>
<br>
I know an alternative to Passive View would be a Supervising Controller,<br>
where the View could take the set of model objects and explicitly map and<br>
create all the columns needed.  e.g. in the controller:<br>
<br>
view.setPeopleList(<wbr>people);<br>
<br>
Since there are requirements that the table column length varies based upon<br>
the data set, and some controls vary based upon permissions, this seems to<br>
encode a lot of responsibility in the view... and that responsibility will<br>
be trickier to test.  (However, GWT does provide a test case which lets you<br>
instantiate widgets in isolation, so perhaps this is another way to test.)<br>
<br>
Can anyone comment on their experiences with this kind of work?<br>
<br>
Thanks,<br>
<br>
Dan<br>
<br>
[Non-text portions of this message have been removed]<br>
<br>
</p>
    </div>  

    <!--~-|**|PrettyHtmlStart|**|-~-->
    <span width="1" style="color: white;">__._,_.___</span>
    <!-- Start the section with Message In topic -->
    <div id="ygrp-actbar">
              <span class="left">
          <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/message/994;_ylc=X3oDMTMyN2JxNjgzBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzk5NARzZWMDZnRyBHNsawN2dHBjBHN0aW1lAzExODU2NzI3ODUEdHBjSWQDOTk0">
            Messages in this topic          </a> (<span class="bld">1</span>)
        </span>
        <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/post;_ylc=X3oDMTJvMWV2Y28zBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzk5NARzZWMDZnRyBHNsawNycGx5BHN0aW1lAzExODU2NzI3ODU-?act=reply&messageNum=994">
          <span class="bld">
            Reply          </span> (via web post)
        </a>  | 
        <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/post;_ylc=X3oDMTJlcXJvNmkyBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTE4NTY3Mjc4NQ--" class="bld">
          Start a new topic        </a>
          </div> 
    <!-------     Start Nav Bar  ------>
    <!-- |**|begin egp html banner|**| -->
    <div id="ygrp-vitnav">
                <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/messages;_ylc=X3oDMTJlN281bXNwBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA21zZ3MEc3RpbWUDMTE4NTY3Mjc4NQ--">Messages</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/files;_ylc=X3oDMTJmaXNkb3U5BF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2ZpbGVzBHN0aW1lAzExODU2NzI3ODU-">Files</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/photos;_ylc=X3oDMTJlMDdyMjFrBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3Bob3QEc3RpbWUDMTE4NTY3Mjc4NQ--">Photos</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/links;_ylc=X3oDMTJmZ3QydmtuBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2xpbmtzBHN0aW1lAzExODU2NzI3ODU-">Links</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/database;_ylc=X3oDMTJjNDloMmJsBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2RiBHN0aW1lAzExODU2NzI3ODU-">Database</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/polls;_ylc=X3oDMTJmZnJnMDJuBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3BvbGxzBHN0aW1lAzExODU2NzI3ODU-">Polls</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/members;_ylc=X3oDMTJlcHZxNTM2BF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA21icnMEc3RpbWUDMTE4NTY3Mjc4NQ--">Members</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/calendar;_ylc=X3oDMTJkZ3BpNDlzBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2NhbARzdGltZQMxMTg1NjcyNzg1">Calendar</a>  
    </div>  
    <!-- |**|end egp html banner|**| -->

    <!-- Do not have place to put it yet -->
    <div id="ygrp-grft">
              

          </div>

    <!-- yahoo logo -->
    <!-- |**|begin egp html banner|**| -->
    <div id="ygrp-ft">
      <a href="http://groups.yahoo.com/;_ylc=X3oDMTJkam1hMTg5BF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxMTg1NjcyNzg1">
      <img src="http://us.i1.yimg.com/us.yimg.com/i/yg/img/logo/ma_grp_160.gif" height="15" width="106" border="0" alt="Yahoo! Groups"></a> <br>
      <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/join;_ylc=X3oDMTJmcW5odmEzBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3N0bmdzBHN0aW1lAzExODU2NzI3ODU-">Change settings via the Web</a> (Yahoo! ID required) <br>
      Change settings via email: <a href="mailto:TestFirstUserInterfaces-digest-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=Email Delivery: Digest">Switch delivery to Daily Digest</a> | <a href = "mailto:TestFirstUserInterfaces-traditional-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=Change Delivery Format: Traditional">Switch format to Traditional</a> <br>

      <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces;_ylc=X3oDMTJkNGZiYThuBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2hwZgRzdGltZQMxMTg1NjcyNzg1">
        Visit Your Group 
      </a> |
      <a href="http://docs.yahoo.com/info/terms/">
        Yahoo! Groups Terms of Use      </a> |
      <a href="mailto:TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=">
        Unsubscribe      </a> 
    </div>     <!-- |**|end egp html banner|**| -->
  </div> <!-- ygrp-msg -->

  
  <!-- Sponsor -->
  <!-- |**|begin egp html banner|**| -->
  <div id="ygrp-sponsor" style="width:140px;float: left; clear: none; margin-left: 5px; background:white; margin-bottom:25px ;position:absolute; top:0; right: 0;">
    <!-- Network content -->
    
    <!-- Start vitality -->
    <div id="ygrp-vital">
              <div id="vithd">Recent Activity</div>
        <ul style="list-style-type:none; padding: 0; margin: 2px 0;">
                <li style="clear: both;">
      <div class="ct" style="float: right;"><span style="display:none">&nbsp;</span>3</div>
      <div class="cat"><a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/members;_ylc=X3oDMTJmMmUzaGplBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzExODU2NzI3ODU-">New Members</a></div>
    </li>
  
            
            
            
            
            
        </ul>
            <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces;_ylc=X3oDMTJlazVoZXRkBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTE4NTY3Mjc4NQ--">
        Visit Your Group      </a>
    </div> 
                <div id="hd">SPONSORED LINKS</div>
      <div id="ov">
        <ul>
                    <li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjMWI0MzBzBF9TAzk3MzU5NzE0BF9wAzEEZ3JwSWQDODc0NDcwNARncnBzcElkAzE3MDUwMDcyMDcEc2VjA3NsbW9kBHN0aW1lAzExODU2NzI3ODU-?t=ms&k=Software+development+tool&w1=Software+development+tool&w2=Application+development+software&w3=Development+software&w4=Development+outsourcing+software&w5=Embedded+software+development&c=5&s=168&g=2&.sig=dMdO9VHGmvW_YJCzvobcVA">Software development tool</a></li>
                    <li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjbGtldXRmBF9TAzk3MzU5NzE0BF9wAzIEZ3JwSWQDODc0NDcwNARncnBzcElkAzE3MDUwMDcyMDcEc2VjA3NsbW9kBHN0aW1lAzExODU2NzI3ODU-?t=ms&k=Application+development+software&w1=Software+development+tool&w2=Application+development+software&w3=Development+software&w4=Development+outsourcing+software&w5=Embedded+software+development&c=5&s=168&g=2&.sig=L7Zs-h76VVahdNyx1QnUHg">Application development software</a></li>
                    <li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjdTVxcGtoBF9TAzk3MzU5NzE0BF9wAzMEZ3JwSWQDODc0NDcwNARncnBzcElkAzE3MDUwMDcyMDcEc2VjA3NsbW9kBHN0aW1lAzExODU2NzI3ODU-?t=ms&k=Development+software&w1=Software+development+tool&w2=Application+development+software&w3=Development+software&w4=Development+outsourcing+software&w5=Embedded+software+development&c=5&s=168&g=2&.sig=mgzP-_wxW4LP9qRGd-WceA">Development software</a></li>
                    <li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjM2o2YnVsBF9TAzk3MzU5NzE0BF9wAzQEZ3JwSWQDODc0NDcwNARncnBzcElkAzE3MDUwMDcyMDcEc2VjA3NsbW9kBHN0aW1lAzExODU2NzI3ODU-?t=ms&k=Development+outsourcing+software&w1=Software+development+tool&w2=Application+development+software&w3=Development+software&w4=Development+outsourcing+software&w5=Embedded+software+development&c=5&s=168&g=2&.sig=To5fERSOzD6F-d_wLzNE1w">Development outsourcing software</a></li>
                    <li><a href="http://groups.yahoo.com/gads;_ylc=X3oDMTJjOGlwN29qBF9TAzk3MzU5NzE0BF9wAzUEZ3JwSWQDODc0NDcwNARncnBzcElkAzE3MDUwMDcyMDcEc2VjA3NsbW9kBHN0aW1lAzExODU2NzI3ODU-?t=ms&k=Embedded+software+development&w1=Software+development+tool&w2=Application+development+software&w3=Development+software&w4=Development+outsourcing+software&w5=Embedded+software+development&c=5&s=168&g=2&.sig=uSsL2YUoig8RH1hp4MMhQg">Embedded software development</a></li>
                  </ul>
      </div>
              
    <!-- Network content -->
              <div id="nc">
              <div class="ad">
                      <div id="hd1">Yahoo! Finance</div> 
<p><a href="http://us.ard.yahoo.com/SIG=12jo5lhqh/M=493064.10729649.11333340.8674578/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1185679985/A=4507179/R=0/SIG=12de4rskk/*http://us.rd.yahoo.com/evt=50284/*http://finance.yahoo.com/personal-finance">It's Now Personal</a></p> 
<p>Guides, news,</p> 
<p>advice & more.</p>                   </div>
                    <div class="ad">
                      <div id="hd1">Yahoo! Groups</div> 
<p><a href="http://us.ard.yahoo.com/SIG=12j0fvahm/M=493064.11135488.11710474.8674578/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1185679985/A=4776364/R=0/SIG=11mj2s6kj/*http://advision.webevents.yahoo.com/green/index.html">Going Green</a></p> 
<p>Share your passion</p> 
<p>for the planet.</p>                  </div>
                    <div class="ad">
                      <div id="hd1">Yahoo! Groups HD</div> 
<p><a href="http://us.ard.yahoo.com/SIG=12jtqom0o/M=493064.10972170.11554072.8674578/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1185679985/A=4706130/R=0/SIG=11f8fj6tf/*http://tech.groups.yahoo.com/group/samsunghd/">The official Samsung</a></p> 
<p>Y! Group for HDTVs</p> 
<p>and devices.</p>                  </div>
          </div>
    
  </div>   <!-- |**|end egp html banner|**| -->
  <div style="clear:both; color: #FFF; font-size:1px;">.</div>
</div>   <img src="http://geo.yahoo.com/serv?s=97359714/grpId=8744704/grpspId=1705007207/msgId=994/stime=1185672785/nc1=4507179/nc2=4776364/nc3=4706130" width="1" height="1"> <br>

<span  style="color: white;">__,_._,___</span>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</body>
<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
<style type="text/css">
<!--
#ygrp-mlmsg {font-size:13px; font-family: arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
#ygrp-mlmsg table {font-size:inherit;font:100%;}
#ygrp-mlmsg select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}
#ygrp-mlmsg pre, code {font:115% monospace;*font-size:100%;}
#ygrp-mlmsg * {line-height:1.22em;}
#ygrp-text{
    font-family: Georgia;	
}
#ygrp-text p{
    margin: 0 0 1em 0;
}
#ygrp-tpmsgs{
    font-family: Arial;	
    clear: both;
}
#ygrp-vitnav{
	padding-top: 10px;
	font-family: Verdana;
	font-size: 77%;
	margin: 0;
}
#ygrp-vitnav a{
	padding: 0 1px;
}
#ygrp-actbar{
	clear: both;
	margin: 25px 0;
	white-space:nowrap;
	color: #666;
	text-align: right;
}
#ygrp-actbar .left{
	float: left;
	white-space:nowrap;
}
.bld{font-weight:bold;}
#ygrp-grft{
	font-family: Verdana;
	font-size: 77%;
	padding: 15px 0;
}
#ygrp-ft{
  font-family: verdana;
  font-size: 77%;
  border-top: 1px solid #666; 
  padding: 5px 0; 
}
#ygrp-mlmsg #logo{
  padding-bottom: 10px;
}

#ygrp-vital{
	background-color: #e0ecee;
	margin-bottom: 20px;
	padding: 2px 0 8px 8px;
}
#ygrp-vital #vithd{
	font-size: 77%;
	font-family: Verdana;
	font-weight: bold;
	color: #333;
	text-transform: uppercase;
}
#ygrp-vital ul{
	padding: 0;
	margin: 2px 0;
}
#ygrp-vital ul li{
  list-style-type: none;
  clear: both;
  border: 1px solid #e0ecee;  
}
#ygrp-vital ul li .ct{
  font-weight: bold;
  color: #ff7900;
  float: right;
  width: 2em;
  text-align:right;
  padding-right: .5em;
}
#ygrp-vital ul li .cat{
  font-weight: bold;
}
#ygrp-vital a {
	text-decoration: none;
}

#ygrp-vital a:hover{
  text-decoration: underline;
}

#ygrp-sponsor #hd{
	color: #999;
	font-size: 77%;
}
#ygrp-sponsor #ov{
	padding: 6px 13px;
	background-color: #e0ecee;
	margin-bottom: 20px;
}
#ygrp-sponsor #ov ul{
	padding: 0 0 0 8px;
	margin: 0;
}
#ygrp-sponsor #ov li{
	list-style-type: square;
	padding: 6px 0;
	font-size: 77%;
}
#ygrp-sponsor #ov li a{
	text-decoration: none;
	font-size: 130%;
}
#ygrp-sponsor #nc {
  background-color: #eee;
  margin-bottom: 20px;
  padding: 0 8px;
}
#ygrp-sponsor .ad{
	padding: 8px 0;
}
#ygrp-sponsor .ad #hd1{
	font-family: Arial;
	font-weight: bold;
	color: #628c2a;
	font-size: 100%;
	line-height: 122%;
}
#ygrp-sponsor .ad a{
	text-decoration: none;
}
#ygrp-sponsor .ad a:hover{
	text-decoration: underline;
}
#ygrp-sponsor .ad p{
	margin: 0;
}
o {font-size: 0; }
.MsoNormal {
   margin: 0 0 0 0;
}
#ygrp-text tt{
  font-size: 120%;
}
blockquote{margin: 0 0 0 4px;}
.replbq {margin:4}
-->
</style>
</head>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</html><!--End group email -->


--2Uwxe7lHjejHzx47VnxDCuFYKzESbVt0bVTaG-D--