<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sectio Aurea</title>
	<atom:link href="http://www.sectioaurea.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sectioaurea.com.br</link>
	<description>Tecnologia da Informação Aplicada</description>
	<lastBuildDate>Thu, 19 Apr 2012 11:59:03 +0000</lastBuildDate>
	<language>pt</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Bitmask</title>
		<link>http://www.sectioaurea.com.br/bitmask/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bitmask</link>
		<comments>http://www.sectioaurea.com.br/bitmask/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 12:50:00 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=132</guid>
		<description><![CDATA[Introdução <p>Um dos recursos mais utilizados por programadores em todos os tempos, extremamente rápido, eficiente e prático, chama-se bitmask.</p> <p>Infelizmente tem sido consolidada a visão de que tudo que exige o conhecimento mínimo de programação é ruim, porque diminui a clareza do código. Em &#8220;diminui a clareza do código&#8221; leia: torna o código ilegível para [...]]]></description>
			<content:encoded><![CDATA[<h1>Introdução</h1>
<p>Um dos recursos mais utilizados por programadores em todos os tempos, extremamente rápido, eficiente e prático, chama-se <strong>bitmask</strong>.</p>
<p>Infelizmente tem sido consolidada a visão de que tudo que exige o conhecimento mínimo de programação é ruim, porque diminui a clareza do código. Em &#8220;diminui a clareza do código&#8221; leia: torna o código ilegível para programadores que não sabem programar&#8230; mas tudo bem. O coitado do bitmask sofreu com isso.<span id="more-132"></span></p>
<p>Trata-se de uma ferramenta muito legal para armazenar e comunicar estados compostos por <em>n </em>condições.</p>
<p>Em uma variável tipo <em>byte</em> (em java), você armazena até 7 informações de estado diferentes. Em um <em>short</em> são 15 informações. Sem quaisquer necessidades de computações mirabolantes adicionais.</p>
<p>Aliás se Java tivesse tipos numéricos sem sinais, poderíamos usar os 8 bits de cada <em>byte</em>. Mas isso é outra discussão.</p>
<h1>A Mágica</h1>
<p>Vamos imaginar que estamos vistoriando um carro, e queremos armazenar em uma variável <em>byte</em> as seguintes informações:</p>
<ul>
<li>O carro está com todos os 4 pneus em condições de uso;</li>
<li>O carro possui combustível;</li>
<li>O carro possui óleo de freio;</li>
<li>O carro possui óleo de motor;</li>
</ul>
<p>Atribua uma potência de 2 a cada informação que deseja armazenar, assim:</p>
<ul>
<li>2ˆ0 = 1 -&gt; O carro está com todos os 4 pneus em condições de uso;</li>
<li>2ˆ1 = 2 -&gt; O carro possui combustível;</li>
<li>2ˆ2 = 4 -&gt; O carro possui óleo de freio;</li>
<li>2ˆ3 = 8 -&gt;  O carro possui óleo de motor;</li>
</ul>
<p>Crie uma variável &#8220;estadoDoCarro&#8221; e atribua a ela a soma das condições que correspondem a realidade do carro:</p>
<ul>
<li>2ˆ0 = 1 -&gt; O carro está com todos os 4 pneus em condições de uso;</li>
<li>2ˆ1 = 2 -&gt; O carro possui combustível;</li>
<li>2ˆ2 = 4 -&gt; O carro possui óleo de freio;</li>
</ul>
<p>RESULTADO DA SOMA = <strong>7</strong></p>
<pre class="brush: java; gutter: true">byte estadoDoCarro = 7;</pre>
<p>Para verificar quais as condições satisfeitas basta utilizar o operador &#8216;&amp;&#8217;:</p>
<pre class="brush: java; gutter: true">byte b = 11;
if ((b &amp; 1) != 0)
   System.out.println(&quot;O carro está com todos os 4 pneus em condições de uso;&quot;);
if ((b &amp; 2) != 0)
   System.out.println(&quot;O carro possui combustível;&quot;);
if ((b &amp; 4) != 0)
   System.out.println(&quot;O carro possui óleo de freio;&quot;);
if ((b &amp; 8 ) != 0)
   System.out.println(&quot;O carro possui óleo de motor;&quot;);</pre>
<h1 class="brush: java; gutter: true">Qual é o truque?</h1>
<p>Utilizando as potências de 2 estamos &#8220;ligando/desligando&#8221; cada um dos bits, e &#8220;concatenando&#8221; booleans. Veja:</p>
<table>
<tbody>
<tr>
<td>Decimal</td>
<td>Binário</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>10</td>
</tr>
<tr>
<td>4</td>
<td>100</td>
</tr>
<tr>
<td>8</td>
<td>1000</td>
</tr>
<tr>
<td>16</td>
<td>10000</td>
</tr>
</tbody>
</table>
<h1>Observações</h1>
<ul>
<li>Em Java existe a classe java.util.BitSet que pode ser bastante útil para essas representações de estado;</li>
<li>Outros operadores como o &#8216;|&#8217; são úteis para esse tipo de técnica, e devem ser dominados por qualquer programador;</li>
<li>Aqueles ifs acima podem ser facilmente substituidos por um loop;</li>
<li>Cada um dos componentes (as potências de dois), normalmente deve ser armazenada em uma constante.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/bitmask/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Considerações sobre Strings</title>
		<link>http://www.sectioaurea.com.br/consideracoes-sobre-strings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=consideracoes-sobre-strings</link>
		<comments>http://www.sectioaurea.com.br/consideracoes-sobre-strings/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 22:00:24 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=96</guid>
		<description><![CDATA[<p>Talvez a classe String seja uma das 2 ou 3 mais utilizadas da API Java, mas mesmo assim é comum que programados saiam criando &#8220;blah,blah,blah&#8221;, sem ter idéia do que está acontecendo por baixo dos panos, e consequentemente sem poder tomar as melhores decisões com relação à segurança e performance.</p> <p>Seguem algumas considerações sobre Strings [...]]]></description>
			<content:encoded><![CDATA[<p>Talvez a classe String seja uma das 2 ou 3 mais utilizadas da API Java, mas mesmo assim é comum que programados saiam criando &#8220;blah,blah,blah&#8221;, sem ter idéia do que está acontecendo por baixo dos panos, e consequentemente sem poder tomar as melhores decisões com relação à segurança e performance.</p>
<p>Seguem algumas considerações sobre Strings em Java, cujos conhecimentos são importantes para que programadores tomem suas decisões:</p>
<ul>
<li>Uma String é uma cadeia de caracteres. Caracteres em Java são representações no formato UTF-16;<span id="more-96"></span></li>
<li>No código-fonte, uma literal do tipo String é composta por zero ou mais caracteres delimitados por aspas duplas;</li>
<li>Uma  literal do tipo String é <strong>sempre</strong> compilada como um objeto da classe String;</li>
<li>Strings com o mesmo conteúdo  são na verdade <strong>o mesmo objeto</strong>. Observe
<pre class="brush: java; gutter: false">String a = &quot;Teste&quot;, b = &quot;Teste&quot;;
System.out.println(a == b);</pre>
<p>Irá imprimir &#8220;true&#8221;, porque a e b são referências ao <strong>mesmo objeto;</strong></li>
<li>Objetos do tipo String são imutáveis. Sempre que uma instrução altera o conteúdo de uma String, ela está na verdade mudando a referência para um objeto recém-criado, ou um reaproveitado (caso o mesmo valor já exista na memória);</li>
<li>Concatenações entre Strings cujos resultados possam ser inferidos em tempo de compilação são feitas na compilação (entre literais, por exemplo);</li>
<li>Concatenações entre Strings cujos valores não possam ser conhecidos na compilação, implicam na criação de uma nova  instância da classe String;</li>
<li>A classe java.lang.StringBuilder, é uma sequência de caracteres desenvolvida para ser utilizada por uma única thread;</li>
<li>A classe java.lang.StringBuffer, é uma sequência de caracteres desenvolvida para que  suas instâncias possam ser acessadas e modificadas por várias threads de forma segura.</li>
</ul>
<h3>Leituras interessantes:</h3>
<ol>
<li>http://pt.wikipedia.org/wiki/UTF-16</li>
<li>http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5</li>
<li>http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.3</li>
<li>http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html</li>
<li>http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html</li>
</ol>
<p>Existem outras coisas importantes para se saber sobre Strings em Java, mas esse é, na minha opinião o pacote básico.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/consideracoes-sobre-strings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modificador volatile</title>
		<link>http://www.sectioaurea.com.br/modificador-volatile/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=modificador-volatile</link>
		<comments>http://www.sectioaurea.com.br/modificador-volatile/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 15:28:30 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[Concorrência]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=89</guid>
		<description><![CDATA[Contexto <p>Para que se entenda a utilidade e o funcionamento do modificador volatile, é necessário conhecer um pouquinho sobre como programas em Java armazenam e acessam variáveis nas diversas memórias disponíveis em um computador.</p> <p>Tenha em mente as seguintes assertivas (bastante simplificadas):</p> O programa acessa e manipula alguns tipos de memória diferentes: registradores, cache, ram; [...]]]></description>
			<content:encoded><![CDATA[<h1>Contexto</h1>
<p>Para que se entenda a utilidade e o funcionamento do modificador <strong>volatile</strong>, é necessário conhecer um pouquinho sobre como programas em Java armazenam e acessam variáveis nas diversas memórias disponíveis em um computador.</p>
<p>Tenha em mente as seguintes assertivas (bastante simplificadas):</p>
<ul>
<li>O programa acessa e manipula alguns tipos de memória diferentes: registradores, cache, ram;</li>
<li>As diferentes memórias possuem performances diferentes;<span id="more-89"></span></li>
<li>Registrador é um tipo de memória muito cara, que fica dentro do próprio processador e por isso tem velocidade excelente;</li>
<li>Memória cache é um tipo de memória que fica próxima ao processador e normalmente pertence a um dos seguintes 3 grupos: L1 (pequena e rápida, uma por processador), L2 (maior e menos rápida, uma por processador), l3 (bem maior e menos rápida, compartilhada entre processadores);</li>
<li>Alguns computadores não possuem L2 e ou L3, por questões econômicas;</li>
<li>Memória RAM é a memória principal do computador, e a maior entre as que foram citadas. Com a tecnologia atual, ela é sempre muito mais lenta que o processador, e por isso as outras formas de memória são necessárias.</li>
</ul>
<p>Além disso é importante saber que o compilador pode fazer algumas alterações na ordem das instruções do programa, para otimizar o processamento e o acesso à memória, veja o código:</p>
<pre class="brush: java; gutter: true">public class Test{
   int a,b;
   public void escrever(){
      a = 1;
      b = 1;
   }
   public void ler(){
      int lidoA = a;
      int lidoB = b;
      System.out.print(a);
      System.out.println(b);
   }
}</pre>
<p>O compilador e a JVM não provêem qualquer garantia de que as instruções serão executadas na ordem em que foram escritas pelo programador, caso eles entendam que as instruções são independentes. Então, no exemplo acima, caso uma thread chame o método escrever, e outra chame o método ler, o resultado pode ser 00,01,11 ou 10, sem que o programador possa prevê-lo inequívocamente.</p>
<p style="padding-left: 30px;"><strong>Então: Para melhorar a performance, o compilador, a JVM e os processadores armazenam &#8220;cópias locais&#8221; das variáveis em locais de acesso mais fácil (cache), fazendo com que threads diferentes possam ter acesso à versões diferentes das mesmas variáveis. Além disso eles reordenam as instruções de forma a otimizar o acesso e a escrita nas diferentes memórias. Quando há um tempinho disponível as diferentes memórias são sincronizadas, mas não há como prever e garantir quando isso será feito.</strong></p>
<p>Em função de tudo isso, uma determinada thread pode trabalhar sobre um conjunto de dados obsoleto (<em>stale data</em>),</p>
<p>Era necessário haver um mecanismo que garantisse que todas as threads vissem determinadas variáveis com o mesmo valor, o tempo todo.</p>
<h1>Volatile</h1>
<p>O modificador volatile é usado para garantir a consistência do estado de variáveis entre diferentes threads.  Cada leitura a uma variável volatile irá retornar o último valor atribuído a ela por qualquer thread. Para garantir isso as seguintes regras são válidas:</p>
<ul>
<li>O processador e a JVM não podem armazenar variáveis volatile nos registradores;</li>
<li>Escritas em variáveis volatile são imediatamente enviadas dos caches para a memória principal do computador;</li>
<li>Imediatamente antes de retornar o valor de uma variável volatile, o cache correspondente é invalidado, fazendo com que o valor retornado seja aquele presente na memória principal do computador.</li>
</ul>
<p>Além disso, instruções que envolvem variáveis volatile não podem ser reordenadas entre si, e existem grandes restrições quanto à forma como elas podem ser reordenadas com instruções relacionadas às variáveis não-volatile. De fato, instruções que operam sobre variáveis volatile funcionam como entradas e saídas de blocos <em>synchronized, </em>visto que elas provocam a sincronização entre o cache utilizado pela thread e a memória principal do computador.</p>
<p>Naturalmente variáveis volatile, implicam em perda de performance, visto que diminuem a capacidade do compilador otimizar o código, e obrigam o acesso mais frequente e não otimizado a memória principal. Então use com moderação.</p>
<h1>Observações Finais</h1>
<p>Esse artigo é praticamente todo válido para JVM&#8217;s anteriores à 5 e completamente válido para a JVM 5 ou as posteriores.</p>
<p>A JVM 5 implementou a JSR-133 que especifica o &#8220;<em>Java Memory Model</em>&#8220;, que nasceu da percepção de que haviam vários &#8220;buracos&#8221; na forma como programas multi-thread escritos em Java lidavam com a memória, resultando em inconsistências e baixa performance.</p>
<h1>Leituras Importantes</h1>
<ul>
<li>http://informatica.hsw.uol.com.br/memoria-do-computador.htm</li>
<li>http://en.wikipedia.org/wiki/Java_Memory_Model</li>
<li>http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/modificador-volatile/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testes unitários em classes que abrem sockets</title>
		<link>http://www.sectioaurea.com.br/testes-unitarios-em-classes-que-abrem-sockets/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=testes-unitarios-em-classes-que-abrem-sockets</link>
		<comments>http://www.sectioaurea.com.br/testes-unitarios-em-classes-que-abrem-sockets/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 01:34:41 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[I/O]]></category>
		<category><![CDATA[Testes]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=80</guid>
		<description><![CDATA[<p>Ao desenvolver uma aplicação que se conecta com alguns servidores através de sockets, tive dificuldades para identificar uma forma prática e confiável de testar o código responsável pela comunicação com o servidor.</p> <p>Pesquisei bastante pela Internet e a maioria das referências que encontrei indicavam o uso de Mocks para simular a conexão.</p> <p></p> <p>Eu não [...]]]></description>
			<content:encoded><![CDATA[<p>Ao desenvolver uma aplicação que se conecta com alguns servidores através de sockets, tive dificuldades para identificar uma forma prática e confiável de testar o código responsável pela comunicação com o servidor.</p>
<p>Pesquisei bastante pela Internet e a maioria das referências que encontrei indicavam o uso de Mocks para simular a conexão.</p>
<p><span id="more-80"></span></p>
<p>Eu não fiquei satisfeito com isso, pois queria testar a camada de rede sob condições no mínimo realistas. Então escrevi uma classe <strong>EchoServer </strong>que levanta um servidor em uma determinada porta, recebe textos dos clientes e os envia de volta.</p>
<p>Essa abordagem deve resolver as dificuldades de testes, e gerar testes confiáveis para a grande maioria das aplicações que abrem sockets para trocar textos com servidores.</p>
<p>Apesar de a classe não ter nada demais, e ser praticamente igual às que devem ser encontradas em qualquer livro sobre java.nio, ela está disponível neste artigo para aqueles que a quiserem.</p>
<p><a href="http://www.sectioaurea.com.br/wp-content/uploads/2012/01/EchoServer.java_.zip">Arquivo para download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/testes-unitarios-em-classes-que-abrem-sockets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Method Chaining</title>
		<link>http://www.sectioaurea.com.br/method-chaining/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=method-chaining</link>
		<comments>http://www.sectioaurea.com.br/method-chaining/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 19:35:49 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=73</guid>
		<description><![CDATA[<p>Estamos tão acostumados com o padrão Javabean: gets, sets e propriedades privadas, que é comum não refletirmos sobre algumas decisões que tomamos ao definir as interfaces de nossas classes.</p> <p>Uma técnica relativamente comum é o Method Chaining. Trocando em miúdos, bem miúdos, consiste em fazer os seus métodos set retornarem 'this'. Algumas classes da API [...]]]></description>
			<content:encoded><![CDATA[<p>Estamos tão acostumados com o padrão Javabean: gets, sets e propriedades privadas, que é comum não refletirmos sobre algumas decisões que tomamos ao definir as interfaces de nossas classes.</p>
<p>Uma técnica relativamente comum é o Method Chaining. Trocando em miúdos, bem miúdos, consiste em fazer os seus métodos set retornarem <code>'this'</code>. Algumas classes da API Java funcionam assim, veja a documentação de <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html" target="_blank">StringBuffer</a>, por exemplo.</p>
<p>E o que eu ganho com isso?</p>
<p><span id="more-73"></span></p>
<p>Concisão, legibilidade, clareza, praticidade&#8230;</p>
<p>Um código que poderia ser assim:</p>
<pre class="brush: java">stringBuffer.mark();
stringBuffer.position(8);
stringBuffer.reset();</pre>
<p>fica assim:</p>
<pre class="brush: java">stringBuffeer.mark().position(8).reset();</pre>
<p>Bem melhor não?</p>
<p>Como fazer?</p>
<p>Simples, substitua isso:</p>
<pre class="brush: java">public void setName(String name){
   this.name = name;
}
public void setEmail(String email){
   this.email = email;
}</pre>
<p>por isso:</p>
<pre class="brush: java">public User name(String name){
   this.name = name;
   return this;
}
public User email(String email){
   this.email = email;
   return this;
}</pre>
<p>E use assim:</p>
<pre class="brush: java">User u = new User().name(&quot;Fulaninho&quot;).email(&quot;fulaninho@gmail.com&quot;);</pre>
<p>E seja feliz.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/method-chaining/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UMLet</title>
		<link>http://www.sectioaurea.com.br/umlet/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=umlet</link>
		<comments>http://www.sectioaurea.com.br/umlet/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 18:15:09 +0000</pubDate>
		<dc:creator>Diogo Dauster Pontual</dc:creator>
				<category><![CDATA[Arquitetura]]></category>

		<guid isPermaLink="false">http://www.sectioaurea.com.br/?p=65</guid>
		<description><![CDATA[<p>Frequentemente temos que criar diagramas UML para conseguirmos comunicar nossas intenções. Seja para clientes, seja para colegas, seja para colar em um artigo.</p> <p>Eu experimentei um milhão de ferramentas desenvolvidas para esse fim e, sinceramente, nunca havia gostado de nenhuma. Tenho a impressão de que os criadores dessas ferramentas, acham que vão resolver todos os [...]]]></description>
			<content:encoded><![CDATA[<p>Frequentemente temos que criar diagramas UML para conseguirmos comunicar nossas intenções. Seja para clientes, seja para colegas, seja para colar em um artigo.</p>
<p>Eu experimentei um milhão de ferramentas desenvolvidas para esse fim e, sinceramente, nunca havia gostado de nenhuma. Tenho a impressão de que os criadores dessas ferramentas, acham que vão resolver todos os problemas do mundo com um software para criar diagramas, e saem enfiando funções, menus contextuais, drags-and-drops mirabolantes, e criam ferramentas extremamente complicadas, cujos custos com tarefas burocráticas são maiores do que os benefícios adquiridos com os diagramas&#8230; Essa é a minha impressão.<span id="more-65"></span></p>
<p>Mas os meus problemas acabaram. Conheci o UMLet, uma programinha feito em Java, extremamente simples, que suporta diversos diagramas e quase não exige que o &#8220;desenhista&#8221; fique pulando com a mão do mouse para o teclado e vice-versa.</p>
<p>O link é: <a href="http://www.umlet.com" target="_blank">http://www.umlet.com</a> .</p>
<p>Fica a dica&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sectioaurea.com.br/umlet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: www.sectioaurea.com.br @ 2012-05-20 05:35:09 -->
