<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1539752288286250641</id><updated>2012-01-18T22:22:39.377-08:00</updated><category term='funny'/><category term='not_configured'/><category term='free'/><category term='perl'/><category term='singleton'/><category term='gnu'/><category term='freedom'/><category term='mojave'/><category term='corporate'/><category term='eclipsse'/><category term='four'/><category term='/etc/'/><category term='python'/><category term='plugin'/><category term='start'/><category term='.2'/><category term='windows'/><category term='code'/><category term='begin'/><category term='magicgroup'/><category term='c++'/><category term='corporations'/><category term='utility'/><category term='patch'/><category term='linux'/><category term='short program'/><category term='choice'/><category term='java'/><category term='logger'/><category term='vmware'/><category term='programming'/><category term='static'/><category term='better'/><category term='dilbert'/><category term='rc.local'/><category term='music'/><category term='diff'/><category term='bash'/><category term='windows sucks'/><category term='kde4'/><category term='stallman'/><category term='copyright'/><category term='build'/><category term='groovy'/><category term='drm'/><category term='unix'/><category term='windows7'/><category term='fix'/><category term='ubuntu'/><category term='cpp'/><category term='error'/><category term='vista'/><category term='initial'/><title type='text'>Freedom Inc.</title><subtitle type='html'>It's all about your freedom.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7543864764510453261</id><published>2011-03-04T09:38:00.000-08:00</published><updated>2011-03-04T09:53:31.335-08:00</updated><title type='text'>Why I love PostgreSQL</title><content type='html'>What if you have a "users" table, and all the properties for the users are in the "property" table. Would a select like this be efficient in PosgreSQL?&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;select distinct u.*, p3.value&lt;br /&gt;from users u&lt;br /&gt;join property p1 on u.id = p1.user_id&lt;br /&gt;join property p2 on u.id = p2.user_id&lt;br /&gt;join property p3 on u.id = p3.user_id&lt;br /&gt;where p1.name = 'admin' and p1.value='false'&lt;br /&gt;and p2.name = 'email' and p2.value like '%mah%'&lt;br /&gt;and p3.name = 'name'&lt;br /&gt;order by p3.value;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Surprisingly this is quite OK, since PostgreSQL won't be stupid enough to do the full Cartesian product.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-l4_74i7oBnA/TXEjy1WnzOI/AAAAAAAAAI8/-Ij4Jfetw48/s1600/Capture.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 361px;" src="http://2.bp.blogspot.com/-l4_74i7oBnA/TXEjy1WnzOI/AAAAAAAAAI8/-Ij4Jfetw48/s400/Capture.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5580280769511148770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I love you PosgreSQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7543864764510453261?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7543864764510453261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7543864764510453261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7543864764510453261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7543864764510453261'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2011/03/why-i-love-postgresql.html' title='Why I love PostgreSQL'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-l4_74i7oBnA/TXEjy1WnzOI/AAAAAAAAAI8/-Ij4Jfetw48/s72-c/Capture.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-2336454169193756375</id><published>2011-02-07T03:08:00.000-08:00</published><updated>2011-02-07T03:11:29.853-08:00</updated><title type='text'>Oracle repents.</title><content type='html'>Oooooo. Just watch the progress.&lt;br /&gt;&lt;br /&gt;Before...&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ie5BPcoUm-I/TU_TDPxfyeI/AAAAAAAAAIg/CQ9rdi7ssDU/s1600/oraclebefore.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 196px;" src="http://1.bp.blogspot.com/_ie5BPcoUm-I/TU_TDPxfyeI/AAAAAAAAAIg/CQ9rdi7ssDU/s400/oraclebefore.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5570903316807797218" /&gt;&lt;/a&gt;&lt;br /&gt;... and after ...&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/TU_TKoj0gZI/AAAAAAAAAIo/dZvNK3UMYP8/s1600/oracleprogress.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 140px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/TU_TKoj0gZI/AAAAAAAAAIo/dZvNK3UMYP8/s400/oracleprogress.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5570903443720405394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Still from &lt;a href="http://www.oracle.com/technetwork/index.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Nice one Oracle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-2336454169193756375?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/2336454169193756375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=2336454169193756375' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2336454169193756375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2336454169193756375'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2011/02/oracle-repents.html' title='Oracle repents.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ie5BPcoUm-I/TU_TDPxfyeI/AAAAAAAAAIg/CQ9rdi7ssDU/s72-c/oraclebefore.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8216818792782650873</id><published>2010-09-09T05:42:00.000-07:00</published><updated>2010-09-09T05:46:42.464-07:00</updated><title type='text'>Java Developers - The bums of the software community at Oracle</title><content type='html'>They can't even afford a shirt like sysadmins and non-java developers.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/TIjW5Z0emSI/AAAAAAAAAH4/gdZdlZaa1RE/s1600/javabums.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 196px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/TIjW5Z0emSI/AAAAAAAAAH4/gdZdlZaa1RE/s400/javabums.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5514894025387055394" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From &lt;a href="http://www.oracle.com/technetwork/index.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8216818792782650873?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8216818792782650873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8216818792782650873' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8216818792782650873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8216818792782650873'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/09/java-developers-bums-of-software.html' title='Java Developers - The bums of the software community at Oracle'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ie5BPcoUm-I/TIjW5Z0emSI/AAAAAAAAAH4/gdZdlZaa1RE/s72-c/javabums.PNG' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8698420802387108401</id><published>2010-04-19T12:27:00.000-07:00</published><updated>2010-04-19T12:40:35.425-07:00</updated><title type='text'>Struts2 Best Practices</title><content type='html'>&lt;p&gt;After reading Struts 2 in Action (a definite read for people who have no experience at all using struts 2), and after finishing a project and actually delivering it to the customer, and in the middle of the second one, I've decided to write down the best practices that I follow.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The reason why i'm writing this is that I couldn't find real case examples of good patterns to follow in developing a struts2 application, even the best practices from that book are quite slim, and I'm not going to reiterate them here.&lt;/p&gt;&lt;br /&gt;&lt;b&gt;Tooling&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt; Buy IntelliJ Idea. I have no words to describe how much more advanced is this compared to eclipse. Jump to definitions of actions, jump to implementing classes, you can pick what action you want to go to from a class (if multiple actions are mapped to the same class), etc. Simply outstanding. &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Buy JRebel if you have I18N in your application. Although they brag to have struts2 support I couldn't make it work (even if conforming to their website should be "brainless" to do it). What it does well though is reloading of classes (like adding methods and co.) and bundle reloading.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Programming Style&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;&lt;b&gt;Don't write any code until you fully understand the ActionContext and the ValueStack&lt;/b&gt;, and how the property resolving takes place. Otherwise all the iterators and push constructs in the JSP will simply look like voodoo (I am talking from experience here).&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;b&gt;Write tests for your actions&lt;/b&gt;. It does seem a bit hard, but it is actually quite simple. Just add this dependency in your maven2 pom.xml file, and just create tests:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;dependency&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;groupId&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;org.apache.struts&lt;font color="#008b8b"&gt;&amp;lt;/groupId&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;artifactId&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;struts2-junit-plugin&lt;font color="#008b8b"&gt;&amp;lt;/artifactId&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;version&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;2.1.8.1&lt;font color="#008b8b"&gt;&amp;lt;/version&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#008b8b"&gt;&amp;lt;/dependency&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;b&gt;Don't create actions with multiple methods&lt;/b&gt;. "execute" and the operation you want to execute (e.g. "createUser") should be enough. Execute would be used for rendering a jsp/ftl/vtl template, and the action will be used to actually do your business requirement.&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;p&gt;&lt;b&gt;All your validations, try to express them via annotations on the business method&lt;/b&gt; (@Validations), and if you can't since they're to complex, and expressions won't cut it, simply implement the validate() action. &lt;b&gt;Never put validations in the model (if you're using ModelDriven actions)&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;The reason is that you always have to check two files in order to see if the business method will be called.&lt;/p&gt;&lt;p&gt;Another thing to keep in mind is if you use annotations AND multiple methods, struts 2 for some reasons collects all the annotations from all the methods and applies them against the current method being called. (as of 2.1.8.1)&lt;/p&gt;&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;b&gt;Use only one I18N package.properties file for the whole project&lt;/b&gt;. If the project gets big it's hard to track which key is where and you'll end up with lots of duplicate keys, and the fear of deleting the keys since you don't know who uses them will be there constantly; unless you're doing some funky searches against the package name in the java sources, and in the struts.xml config files.&lt;br/&gt;&lt;br /&gt;        Not fun at all.&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;    &lt;li&gt;&lt;b&gt;Preffer interceptors over servlet filters&lt;/b&gt;. The only reason why you would want servlet filters is to intercept resources that are not actions. Otherwise the access to the ActionContext is invaluable. Both of them are fairly lightweight so I see no reason in having things that do the same thing in two places (web.xml and struts.xml).&lt;br /&gt;    &lt;/li&gt; &lt;br /&gt;    &lt;li&gt;&lt;p&gt;&lt;b&gt;Create interceptors to inject services for you&lt;/b&gt; (like EJBs, or whatever counterparts are in spring).  Your methods in the action should become simple wrappers over the actual business services. Also it becomes trivial to test, since the tests will also simply inject mocks of the actual services.&lt;/p&gt;&lt;p&gt;Don't be afraid to create custom interceptors for whatever you need them. They are extremely lightweight&lt;/p&gt;&lt;br /&gt;    &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;A "full" action implementation would be along these lines, so it is imediatelly clear what it does, what validations does it require, and is trivial to test:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;RegisterUserAction &lt;font color="#2e8b57"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ActionSupport {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;// ...&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;String username; &lt;font color="#0000ff"&gt;// + getter/setter&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;@EJB&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;UserService userService; &lt;font color="#0000ff"&gt;// no getter/setter, set by interceptor&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;validate()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;// custom complex validations&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;@Validations&lt;/font&gt;(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;// ... most of the time validate() is not needed.&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;String registerUser()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;userService.registerUser(username);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;font color="#a52a2a"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(Exception e)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LOG.error(e, e);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;addFieldError(&lt;font color="#ff00ff"&gt;&amp;quot;some_field&amp;quot;&lt;/font&gt;, getText(&lt;font color="#ff00ff"&gt;&amp;quot;some_specific_error_key&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;INPUT;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SUCCESS;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;// execute is mapped as excluded in struts.xml for validations&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;String execute()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SUCCESS;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;// ...&lt;/font&gt;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That would be it. As usual, I'm extremely interested in your feedback.&lt;br /&gt;&lt;br /&gt;Have fun programming with struts 2.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8698420802387108401?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8698420802387108401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8698420802387108401' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8698420802387108401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8698420802387108401'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/04/struts2-best-practices.html' title='Struts2 Best Practices'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-1082840350309965016</id><published>2010-03-06T15:12:00.000-08:00</published><updated>2010-03-06T15:17:50.923-08:00</updated><title type='text'>MagicGroup 1.3.0 is out</title><content type='html'>Hi, for all of you tracking MagicGroup, version 1.3.0 is out.&lt;br /&gt;&lt;br /&gt;It features a number of bugfixes (like when having a file with the same time multiple times in a group and deleting it, or a NPE that happened once in a blue moon), but most important it adds descriptions to the files.&lt;br /&gt;&lt;br /&gt;Thus you can click now on a file/group, and then press the pencil button and edit the descriptions for the item. The short description is appended to the file name in the tree view, the long description is visible in a tool tip on mouse over over the file/group.&lt;br /&gt;&lt;br /&gt;I needed it since I had a maven2 project and all my files were pom.xml, pom.xml, etc :) for all the project. Not very helpful as you can imagine.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/S5LiF03bFNI/AAAAAAAAAHo/DwoXY1vhjCA/s1600-h/magicgroup-1.3.0.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 311px; height: 400px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/S5LiF03bFNI/AAAAAAAAAHo/DwoXY1vhjCA/s400/magicgroup-1.3.0.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445663489162679506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As usual, you can download it from here:&lt;br /&gt;&lt;a href="https://sourceforge.net/projects/magicgroup/"&gt;https://sourceforge.net/projects/magicgroup/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and sources (mercurial repository) here:&lt;br /&gt;&lt;a href="http://magicgroup.hg.sourceforge.net:8000/hgroot/magicgroup/magicgroup"&gt;http://magicgroup.hg.sourceforge.net:8000/hgroot/magicgroup/magicgroup&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-1082840350309965016?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/1082840350309965016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=1082840350309965016' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1082840350309965016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1082840350309965016'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/03/magicgroup-130-is-out.html' title='MagicGroup 1.3.0 is out'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ie5BPcoUm-I/S5LiF03bFNI/AAAAAAAAAHo/DwoXY1vhjCA/s72-c/magicgroup-1.3.0.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-2693090082850355966</id><published>2010-03-05T10:28:00.000-08:00</published><updated>2010-03-05T10:31:08.053-08:00</updated><title type='text'>My ISP is really cool</title><content type='html'>Your average video speed at this location from February 04, 2010 to March 04, 2010 was 10.85 Mbps.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/S5FNiF4Ch-I/AAAAAAAAAHg/WlfqcMLPWE0/s1600-h/chart2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 218px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/S5FNiF4Ch-I/AAAAAAAAAHg/WlfqcMLPWE0/s400/chart2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445218672555755490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ie5BPcoUm-I/S5FNeU-siOI/AAAAAAAAAHY/GMgdaThgWyQ/s1600-h/chart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 293px;" src="http://1.bp.blogspot.com/_ie5BPcoUm-I/S5FNeU-siOI/AAAAAAAAAHY/GMgdaThgWyQ/s400/chart.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5445218607890729186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pretty much ownage.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-2693090082850355966?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/2693090082850355966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=2693090082850355966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2693090082850355966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2693090082850355966'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/03/my-isp-is-really-cool.html' title='My ISP is really cool'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ie5BPcoUm-I/S5FNiF4Ch-I/AAAAAAAAAHg/WlfqcMLPWE0/s72-c/chart2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4151325195628194423</id><published>2010-02-28T15:42:00.000-08:00</published><updated>2010-02-28T15:51:47.833-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='magicgroup'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipsse'/><title type='text'>MagicGroup 1.2.1 released today.</title><content type='html'>It is with great joy, that I announce the release of version 1.2.1 of &lt;a href="http://freeopenidea.blogspot.com/2008/06/beauty-of-opensource.html"&gt;MagicGroup&lt;/a&gt;, available at:&lt;br /&gt;&lt;a href="https://sourceforge.net/projects/magicgroup/files/"&gt;https://sourceforge.net/projects/magicgroup/files/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;MagicGroup is an eclipse plugin that facilitates the organisation of files in a logical structure, not bounded by the file system structure, especially useful when learning frameworks.&lt;br /&gt;&lt;br /&gt;Change log:&lt;br /&gt;* Saving groups take place now in the workspace folder, instead of the eclipse project folder.&lt;br /&gt;* Accessing of the files takes place via the portable path instead of absolute path, thus some issues when opening files (synchronisation with projects, autocomplete) should be fixed.&lt;br /&gt;&lt;br /&gt;You can checkout the source from here (mercurial):&lt;br /&gt;&lt;a href="http://magicgroup.hg.sourceforge.net:8000/hgroot/magicgroup/magicgroup"&gt;http://magicgroup.hg.sourceforge.net:8000/hgroot/magicgroup/magicgroup&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4151325195628194423?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4151325195628194423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4151325195628194423' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4151325195628194423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4151325195628194423'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/02/magicgroup-121-released-today.html' title='MagicGroup 1.2.1 released today.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5643624391709997338</id><published>2010-02-22T21:47:00.000-08:00</published><updated>2010-02-22T22:23:19.273-08:00</updated><title type='text'>KDE network manager mockup</title><content type='html'>As you might know, the "JavaScript Jam Sessions" contest is on the way, at &lt;a href="http://plasma.kde.org/"&gt;plasma.kde.org&lt;/a&gt;. Since I've realized that I don't have enough time or energy to implement it, but I would love to see it in the KDE desktop, I've decided to release the design for public use.&lt;br /&gt;&lt;br /&gt;If it's going to be done in javascript or python, I would love to take a look and help (even if the entry will be used for the contest, I have no interest in the prizes).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/S4NwaDqet7I/AAAAAAAAAHQ/viVBbIkFHts/s1600-h/kwifiman.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 213px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/S4NwaDqet7I/AAAAAAAAAHQ/viVBbIkFHts/s400/kwifiman.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5441316367756081074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The idea as you can see is to display the wireless networks in a more accessible way, sorted by signal strength. Eventual metadata about them (encryption mostly) can be presented as the small black pills on top of the icon.&lt;br /&gt;&lt;br /&gt;Connections to the wireless network should be presented dotted, the ones to the wired lines as a straight line (you can see that we have a connection to a wireless access point).&lt;br /&gt;&lt;br /&gt;If the Internet is accessible the blue globe from the top right should be blue, otherwise it should be grayed out.&lt;br /&gt;&lt;br /&gt;Here is my &lt;a href="http://kde-look.org/content/show.php?content=120635"&gt;kde-look entry&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can download &lt;a href="http://download.androidknight.com/design-wifi-manager/"&gt;the full XCF (gimp) file from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5643624391709997338?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5643624391709997338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5643624391709997338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5643624391709997338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5643624391709997338'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/02/kde-network-manager-mockup.html' title='KDE network manager mockup'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/S4NwaDqet7I/AAAAAAAAAHQ/viVBbIkFHts/s72-c/kwifiman.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5844429827122614196</id><published>2010-01-20T08:39:00.000-08:00</published><updated>2010-01-21T06:37:38.592-08:00</updated><title type='text'>Drowning in Struts2</title><content type='html'>We are building a Struts2 application. Yay!&lt;br /&gt;We are building a Struts 2 component. Yay!&lt;br /&gt;We're going to use several programming languages for that. Yay! Wait, what?!&lt;br /&gt;&lt;br /&gt;Here is a tiny snippet from a much larger (and cryptic looking code calendar component) we had to develop:&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;td&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;dateDMHM&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;2 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;@s&lt;/font&gt;&lt;font color="#0000ff"&gt;.&lt;/font&gt;&lt;font color="#008b8b"&gt;textfield&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;id&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;${parameters.name}.hour&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;3 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;name&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;${parameters.name}.hour&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;4 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onfocus&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;if(this.value=='hh')this.value=''&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;5 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onblur&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;if(this.value=='')this.value='hh'&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onchange&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;setChecked('true', '${parameters.id}_true')&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;/&amp;gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/td&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;td&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;dateText&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;.&lt;font color="#008b8b"&gt;&amp;lt;/td&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;td&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;dateDMHM&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008b8b"&gt;@s&lt;/font&gt;&lt;font color="#0000ff"&gt;.&lt;/font&gt;&lt;font color="#008b8b"&gt;textfield&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;id&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;${parameters.name}.minute&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;name&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;${parameters.name}.minute&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;12 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onfocus&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;if(this.value=='mm')this.value=''&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;13 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onblur&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;if(this.value=='')this.value='mm'&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;14 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;onchange&lt;/b&gt;&lt;/font&gt;=&lt;font color="#ff00ff"&gt;&amp;quot;setChecked('true', '${parameters.id}_true')&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;/&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;15 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/td&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Can you tell how many languages are being used in this &lt;b&gt;freemarker&lt;/b&gt; (1) from a Struts2 application snippet of code?&lt;br /&gt;td - plain &lt;b&gt;HTML&lt;/b&gt; (2)&lt;br /&gt;class="dateDMHM" - with &lt;b&gt;CSS&lt;/b&gt; (3)&lt;br /&gt;@s.textfield - &lt;b&gt;struts2 tags&lt;/b&gt; (4) available in the freemarker, offered transparently by struts2 engine &lt;br /&gt;onfocus="..." - &lt;b&gt;JavaScript&lt;/b&gt; (5)&lt;br /&gt;&lt;br /&gt;even if it looks innocent, that id="${parameters.name}.minute" is actually an &lt;b&gt;OGNL&lt;/b&gt; expression (6).&lt;br /&gt;&lt;br /&gt;This component is being used as a result in a &lt;b&gt;JSP&lt;/b&gt; file (7) from an action implemented in &lt;b&gt;Java&lt;/b&gt; (8).&lt;br /&gt;&lt;br /&gt;Even if we can say that we can ignore HTML, CSS and JavaScript since they are ubiquitous, we still have 5 languages to master in order to build one application.&lt;br /&gt;&lt;br /&gt;Compare this with a normal JSF (+xhtml) stack that brings you 2 new languages: JSF and Java.&lt;br /&gt;&lt;br /&gt;Don't get me wrong I do believe that struts2 is a decent framework, but in the languages area I think it's a bit too much.&lt;br /&gt;&lt;br /&gt;Note: I could say 3 languages on JSF's part: JSF, Java &lt;i&gt;and EL&lt;/i&gt;, but I would have to add EL as also being available in JSP, thus 9 languages for the Struts2.&lt;br /&gt;Note 2: I know we can completely remove JSP from the picture, and use freemarker templates directly, but I doubt that would be a "normal" Struts2 application stack.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5844429827122614196?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5844429827122614196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5844429827122614196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5844429827122614196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5844429827122614196'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/01/drowning-in-struts2.html' title='Drowning in Struts2'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4363199750889740179</id><published>2010-01-17T15:14:00.000-08:00</published><updated>2010-01-17T15:44:16.620-08:00</updated><title type='text'>Bring 'em hell!</title><content type='html'>Do you remember when &lt;a href="http://googleblog.blogspot.com/2010/01/new-approach-to-china.html"&gt;google said they will pack their toys&lt;/a&gt; and leave since China hacked into some human right activists accounts?&lt;br /&gt;&lt;br /&gt;The cool part is that initially China wanted to play down the move from google, &lt;a href="http://news.bbc.co.uk/2/hi/asia-pacific/8458462.stm"&gt;saying that they (google) broke the law, thus they can leave&lt;/a&gt;, BUT the rest of the economic environment should have no fears, since China is not going to disrupt their business.&lt;br /&gt;&lt;br /&gt;IMHO Google played China like a violin pretty much saying, "You don't care what we're going to do? Then you shall kick us out.", and started &lt;a href="http://www.google.cn/search?hl=zh-CN&amp;q=tiananmen+massacre&amp;btnG=Google+%E6%90%9C%E7%B4%A2&amp;aq=f&amp;oq="&gt;giving results uncensored&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I find this brilliant since now China is in a no win situation. They can let google operate uncensored, but this goes against their policy, or they can kick google out, but I bet in that very moment all the Asian stocks will sink, since now China contradicts itself as not disrupting business and offering guarantees of a stable market environment.&lt;br /&gt;&lt;br /&gt;With &lt;a href="http://news.bbc.co.uk/2/hi/asia-pacific/8462889.stm"&gt;the US government backing google&lt;/a&gt; it's a hell ride for China.&lt;br /&gt;&lt;br /&gt;And I love it.&lt;br /&gt;&lt;br /&gt;Why? Because google said implicitly this to me, and all others who have e-mails on google: "If any entity will try to use your private e-mails hosted on our servers against you, and against your will, we will bring them hell".&lt;br /&gt;&lt;br /&gt;Thank you google!&lt;br /&gt;&lt;br /&gt;And for all the people still using Internet Explorer out there, &lt;a href="http://news.bbc.co.uk/2/hi/technology/8460819.stm"&gt;I hope one day you'll learn your lesson&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4363199750889740179?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4363199750889740179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4363199750889740179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4363199750889740179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4363199750889740179'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2010/01/bring-em-hell.html' title='Bring &apos;em hell!'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7727489553823489844</id><published>2009-11-30T02:20:00.000-08:00</published><updated>2009-12-01T05:06:42.348-08:00</updated><title type='text'>Low level vs high level tools</title><content type='html'>ComputerWorld posted a "debate" using high level tools (like integrated tools as Visual Studio) against basic ones (a basic text editor, command line compilers). The &lt;a href="http://www.computerworld.com/s/article/9141465/Microsoft_s_top_developers_prefer_old_school_coding_methods"&gt;original article is here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I think that many persons talk to promote the products they're working on: is natural for a shell creator to encourage all people to use "basic stuff", as a C++/CLI creator will want people to write more in C++ as this is his/hers language, and not in C# (it's closest competitor). They use arguments like "abstraction penalty" as an argument for their tools working faster, since they aren't doing indirected calls and use (more directly) components without their associated cost.&lt;br /&gt;&lt;br /&gt;I will take one at a time:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;using text editor/command line compiler against using a high level IDE&lt;/span&gt;. The reason I would firstly use an IDE is that it organizes and simplifies most operations. Even if I will have to learn some operations that the IDE supports, like Refactorings (which are not a part of the text editors at all) which do permit you to reorganize your code, on the long run many faults such as misspellings are not done just because the IDE helps you write your code right. Exposing too much information might be tricky, but I think it's rarely shown to be as a big issue as to forgot to add a file into SVN. From this regard, in general the IDE makes me think on problem itself, not on spelling and how to put all the compiler arguments right. For example Eclipse has many perspectives, each with its own tools being shown, directed at an angle in which you want to see your problem from. If you just need to change a line, probably VIM is a much better option, but sticking to Eclipse it will fix your Java deployment into jars, will integrate with your SVN/Mercurial/etc. local changes, and you will not need to put on sticky notes all arguments that you've missed, and thus needed to recompile.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;span style="font-weight: bold;"&gt;Managed code also lets developers "perform above their level of competence,"&lt;/span&gt;  &lt;managed&gt;This is really tricky if you don't know what managed code is in detail. You can translate this statement as: a virtual machine doesn't let you express at your level of competence, since most of the constructions that you normally would create are already there. Many design decision, that a virtual machine has implemented, are to prevent anti-patterns and to force developers to stay in the VM's sandbox. To put this in a UNIX perspective, the problem is like: the limited user will not let you express yourself since you are not administrator/root. But as administrator/root you can break your system, and there is a high risk that the problems you will encounter or create will have a greater damage, for no real benefit. Yes there might be leaks inside VMs but in the most cases they aren't. So you can simply work with your preferred VM code in Java/C# and at the end of the day the quantity of your issues that you'll find will be smaller&lt;br /&gt;&lt;/managed&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Abstraction penalty will make the trend: people will go to low level languages which do bring performance for future.&lt;/span&gt;  The problem with JIT in particulars and their lack of speed is simple: the JITs are actually fast enough. Probably a JIT means at most to cut the speed in two compared with C++. In fact Java with Java 7 will improve once again performance of their running bytecode. This will mean a lot of applications will run just fast enough. Also, most applications are not games nor renderers. As for me, I am sure that Windows Vista/Windows 7 could be written as shell parts in .NET. The biggest proof is Paint.NET and the Linux's Mono application set. I am agreeing with the abstraction payment as long as you really depend on them (for example, please don't garbage collect while you're running my pacemaker. Thank you). But in fact being inside a VM will only mean to you that your runtime environment will be much easier to be fixed and upgraded, and your code will be much easily run on any platform that supports your VM.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;The point I wanna make is just this: for many mediocre programmers, writing yet another algorithm using low level things is unlikely, and in most cases will not run as fast as the as the same C#/Java code on the long run. Even when you will write everything perfectly, a new version of your virtual machine will get the code so close to your hard optimized code that will make all the extra effort worthless. Using IDEs will simply make your working procedure simpler.&lt;p/&gt;So, why use notepad when you have Eclipse?&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7727489553823489844?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7727489553823489844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7727489553823489844' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7727489553823489844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7727489553823489844'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/11/low-level-vs-high-level-tools.html' title='Low level vs high level tools'/><author><name>ciplogic</name><uri>http://www.blogger.com/profile/05409605028353356569</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-1029860827355882236</id><published>2009-11-18T08:46:00.000-08:00</published><updated>2009-11-18T08:55:38.691-08:00</updated><title type='text'>Internet-Enabled Devices in Microsoft's Vision</title><content type='html'>I can't make this kind of stuff up. This is an actual opensource release from Microsoft:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"Microsoft has released &lt;b&gt;part of its .NET Framework - the part for internet-connected smart devices&lt;/b&gt; - into the open-source community. [...] But don't get too excited. You won't be getting the full .NET Micro Framework stack, as Microsoft's open-source code donation &lt;b&gt;will lack the TCP/IP stack and cryptography libraries.&lt;/b&gt;"&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So let's recap: .NET for "Internet-enabled smart devices" with no TCP/IP nor security?! Wow! I'm really impressed.&lt;br /&gt;&lt;br /&gt;What's next, really? Because this one definitely blew my mind.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.theregister.co.uk/2009/11/16/dot_net_micro_framework_open_sourced/"&gt;full article is here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-1029860827355882236?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/1029860827355882236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=1029860827355882236' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1029860827355882236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1029860827355882236'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/11/internet-enabled-devices-in-microsofts.html' title='Internet-Enabled Devices in Microsoft&apos;s Vision'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-3016921621335270291</id><published>2009-11-12T07:26:00.000-08:00</published><updated>2009-11-14T19:15:40.236-08:00</updated><title type='text'>DroidCan't</title><content type='html'>I had the opportunity to see the commercials from Motorola with iDon't. While I found it cool to slander the iPhone platform (Mac vs PC anyone?) I've started receiving lately some bad reviews for my application from some droid users.&lt;br /&gt;&lt;br /&gt;Ok, I had bad reviews even before, no biggie, but these ones were like: "it doesn't work on Droid". Thus I started tracking one guy who gave AndroidKnight one star, and here is a screenshot with what other applications he gave bad ratings:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ie5BPcoUm-I/SvwqsMy63rI/AAAAAAAAAHE/lsE1hKU2lk4/s1600-h/badratings.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 381px;" src="http://1.bp.blogspot.com/_ie5BPcoUm-I/SvwqsMy63rI/AAAAAAAAAHE/lsE1hKU2lk4/s400/badratings.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5403240591775162034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wow... dedicated guy.&lt;br /&gt;&lt;br /&gt;See a pattern? All of them are 3D applications, and this disgruntled user managed to give 5 stars to an application which wasn't 3D. (To be honest, I would be also filled with rage after paying &lt;a href="http://www.mobilecityonline.com/wireless/store/productdetail.asp?productid=25347&amp;refid=froogle&amp;utm_source=froogle&amp;utm_medium=organic&amp;utm_term=MOTDROIDBKEU&amp;utm_campaign=froogle"&gt;more than 500 bucks&lt;/a&gt; to find out that no OpenGL application works).&lt;br /&gt;&lt;br /&gt;Thus I thought "dude, that must be some mistake Motorola did, probably some weird API they've added, but I'll just download their SDK, do a trick or two, and it would be up and running in no time". Turns out &lt;a href="http://community.developer.motorola.com/mtrl/board/message?message.uid=2675"&gt;I was wrong&lt;/a&gt;. There is no customization in the software that Motorola provided with their phone.&lt;br /&gt;&lt;br /&gt;As Graig Wilson (from Motorola) said it in plain English:&lt;br /&gt;&lt;blockquote&gt;You already have it, if you have the new Google 2.0 SDK. Droid has no "Moto customizations"; the software on the shipping device is the Android 2.0 platform, straight from Google. So the emulator that Google provides really is the emulator for the shipping device.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Well guess what: AndroidKnight (and I am willing to bet every other 3D application from that list) works under the emulator. For 2.0, of course.&lt;br /&gt;&lt;br /&gt;It's a bit frustrating knowing that just disabling the hardware acceleration on Droid would probably "fix" it.&lt;br /&gt;&lt;br /&gt;So this brings me to this very simple point: I don't know if it is the fault of Google or Motorola. (I've heard Galaxy from Samsung has the same issues, so I tend to believe it's Google).&lt;br /&gt;&lt;br /&gt;To be honest I don't really care that much.&lt;br /&gt;&lt;br /&gt;But think for a minute or two, what does it matter if you have some "cool" phone which doesn't do some basic stuff that it &lt;b&gt;is supposed to do&lt;/b&gt;. Because the iPhone wasn't designed to have a real keyboard/run multiple apps/run widgets/etc. No one sells iPhones for that, they sell it with just one saying: "it just works".&lt;br /&gt;&lt;br /&gt;Ok, enough ranting, what is my proposed solution?&lt;br /&gt;&lt;br /&gt;Make google enforce a suite of tests that every phone should pass before it can be named android compatible. If they don't pass the tests, they shouldn't be allowed to run an operating system named android (enforce the trademark), but rather they should be forced to rename their operating system (so they can still use the same sources if they want).&lt;br /&gt;&lt;br /&gt;Otherwise it will simply be DroidCan't too.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;&lt;br /&gt;Turns out that &lt;a href="http://www.mail-archive.com/android-developers@googlegroups.com/msg65021.html"&gt;other people had issues as well&lt;/a&gt; and tried to figure them out. Please read that link since it might give insightful information on what you need to do next.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://android-developers.blogspot.com/2009/04/introducing-glsurfaceview.html"&gt;This read&lt;/a&gt; might also help.&lt;br /&gt;&lt;br /&gt;At the moment I'm trying to change the initialization code &lt;a href="http://gitorious.org/0xdroid/frameworks_base/blobs/93f411386a570082f25996cb373bc338c6beee7a/opengl/java/android/opengl/GLSurfaceView.java#line653"&gt;to look more like here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update 2&lt;/b&gt;&lt;br /&gt;This code works for RED = 5, GREEN  = 6, BLUE = 5, ALPHA = 0, DEPTH = 16 and STENCIL = 8. Note that in my code DEPTH is the minimal DEPTH, but I will give better distances if the DEPTH is actually higher that the DEPTH value.&lt;br /&gt;&lt;div style="border: 1px solid black; font-family: monospace; font-size: 10px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EGLConfig[]&amp;nbsp;configs)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;EGLConfig closestConfig = &lt;font color="#ff00ff"&gt;null&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;double&lt;/b&gt;&lt;/font&gt;&amp;nbsp;closestDistance = &lt;font color="#ff00ff"&gt;1000.0&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;idx = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;(EGLConfig config : configs)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;idx++;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, &lt;font color="#ff00ff"&gt;0&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;configCaveat = findConfigAttrib(egl, display, config, EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_NONE);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;double&lt;/b&gt;&lt;/font&gt;&amp;nbsp;distance = Math.sqrt(&amp;nbsp;Math.abs(r - RED)&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ Math.sqrt(&amp;nbsp;Math.abs(g - GREEN)&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ Math.sqrt(&amp;nbsp;Math.abs(b - BLUE)&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ Math.sqrt(&amp;nbsp;Math.abs(a - ALPHA)&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ Math.sqrt(&amp;nbsp;Math.abs(s - STENCIL)&amp;nbsp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ Math.sqrt(&amp;nbsp;&lt;font color="#ff00ff"&gt;128&lt;/font&gt;&amp;nbsp;- d ); &lt;font color="#0000ff"&gt;// prefer bigger depths if available&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.d(&lt;font color="#ff00ff"&gt;&amp;quot;AndroidKnight&amp;quot;&lt;/font&gt;, configToString(config)&amp;nbsp;+ &lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;\n&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;nbsp;distance: &amp;quot;&lt;/font&gt;&amp;nbsp;+ distance);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(d &amp;lt; DEPTH &amp;amp;&amp;amp; configCaveat != EGL10.EGL_NONE)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.d(&lt;font color="#ff00ff"&gt;&amp;quot;AndroidKnight&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;Ignoring config &amp;quot;&lt;/font&gt;&amp;nbsp;+ idx + &lt;font color="#ff00ff"&gt;&amp;quot; since config caveat is : &amp;quot;&lt;/font&gt;&amp;nbsp;+ configCaveat + &lt;font color="#ff00ff"&gt;&amp;quot; and depth is &amp;quot;&lt;/font&gt;&amp;nbsp;+ d);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;continue&lt;/b&gt;&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(distance &amp;lt; closestDistance)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;closestDistance = distance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;closestConfig = config;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Log.d(&lt;font color="#ff00ff"&gt;&amp;quot;AndroidKnight&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;Selected configuration: &amp;quot;&lt;/font&gt;&amp;nbsp;+ configToString(closestConfig));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;closestConfig;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Explanations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I'm using &lt;b&gt;sqrt&lt;/b&gt;, so changes in color bits will have a bigger impact. For example if no configuration matched and simply summing absolute of differences, a target configuration like R:5,G:6,B:5,A:0,S:0,D:16 would yield the same distances for these configurations R:5,G:6,B:5,A:0,S:8,D:16 vs R:8,G:8,B:8,A:0,S:0,D:16 if I would just sum up values. The idea is that I would rather have the bytes per pixels right, than the stencil buffer right from these configurations; especially since it seems its a bpp issue in the first place.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I don't care about the depth as long it is at least the depth required. I actually prefer bigger depths if available.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I don't want any configuration that is not conforming or slow, etc. This is why there is a flag checking. &lt;i&gt;I didn't even knew about it before my saga.&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The reason why stencil is set to 8 (even if I'm not using it) is because it fails to initialize if it is 0 - &lt;i&gt;I might have done something wrong&lt;/i&gt;.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Feel free to use this code as you like.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-3016921621335270291?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/3016921621335270291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=3016921621335270291' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3016921621335270291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3016921621335270291'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/11/droidcant.html' title='DroidCan&apos;t'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ie5BPcoUm-I/SvwqsMy63rI/AAAAAAAAAHE/lsE1hKU2lk4/s72-c/badratings.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5977572431015768915</id><published>2009-10-23T14:57:00.000-07:00</published><updated>2009-10-23T15:02:50.518-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows7'/><category scheme='http://www.blogger.com/atom/ns#' term='windows sucks'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='kde4'/><title type='text'>I give you the newest Windows7 (KDE 4)</title><content type='html'>ZDNet Australia installed in a shop KDE 4, and told people that this is the new Windows7. They presented applications such as amarok, dolhpin, and openoffice.&lt;br /&gt;&lt;br /&gt;See what happened next &lt;a href="http://www.youtube.com/watch?v=T3ID2CbtnKk"&gt;at this link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is priceless. I don't want to be mean, but &lt;a href="http://freeopenidea.blogspot.com/2009/10/windows-is-hot.html"&gt;din't I told you so&lt;/a&gt;? Watch the people's reactions and how they describe it and relate to Vista.&lt;br /&gt;&lt;br /&gt;It is simply unbelievable.&lt;br /&gt;&lt;br /&gt;KDE really made a great product.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5977572431015768915?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5977572431015768915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5977572431015768915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5977572431015768915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5977572431015768915'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/10/i-give-you-newest-windows7-kde-4.html' title='I give you the newest Windows7 (KDE 4)'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8008190926727437295</id><published>2009-10-19T15:57:00.000-07:00</published><updated>2009-10-19T19:07:29.464-07:00</updated><title type='text'>Windows 7 vs. Mac Snow Leopard: The Great Debate (translated)</title><content type='html'>&lt;div style="color : #770000"&gt;The following content is a parody. It is made after &lt;a href="http://www.pcmag.com/article2/0,2817,2354364,00.asp"&gt;this interview&lt;/a&gt; so it would make sense to read that one first. By any means this is not what Brian Coll nor Jay Paulus would have said, but what I in my artistic rambling invented as answers to the questions put by Lance Ulanoff of &lt;a href="http://pcmag.com"&gt;pcmag.com&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;This is for entertainment only and I am not claiming to be factually accurate.&lt;/b&gt;&lt;/p&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Let's start with 64-bit. For perhaps the first time in operating system history, average consumers are aware of the 64-bit choice and thinking about whether or not they need or want to use it. What does Apple and Microsoft bring to the table here?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Well, we have this cool kernel that we taken from BSD, and we are based on a cross-platform UNIX. Not to mention our hardware pool it is quite small, and also we have our own packaging system. To migrate to 64 bit was quite painless. We did a great job about it, so we decided in the end to disable it by default.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: We have two versions. D**n these years of compatibility to keep, they really choke us. And unlike Macs we give our customers options: The option, of reinstalling your Windows and all your other applications whenever you want to switch to 32bit to 64bit and back, is always on the table. We want people to have the chance to install Windows as many times as they want. This is what we call customer choice.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Modern computers now feature multicore CPUs. However, consumers aren't always sure if their operating systems or apps are taking full—or any—advantage of all those cores. What are you guys doing in the multicore space?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: You had to ask this, didn't you? To answer your question though, we provided an API so that the kernel can do threads instead of the developer. It's fantastic, I've heard about it yesterday from Steve, he was realy enthusiastic also. We suport one platform since we all know that cool people use one platform (namely Mac + iTunes).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Thank you for the question. Here we feel we've outdone ourselves: Not only that we have this very cool and technologically advanced hybrid-kernel that works on several platforms, including 64 bit, but we've traded a bit of security over here, a bit of performance and resource usage over there and in the end we got Vista which is perfect on the upgrade path to a much needed new PC and new hardware. And you can still get viruses.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Okay, let's step out from under the hood and talk about what consumers see on their desktops, specifically, the UI?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Well, our customers are licking their screens since 2002. I think that said it right there. But still, if you want me to continue, dock is simply cool, we have cool effects that actually help you, we have Cover Flow to search for stuff and Time Machine which is integrated with your desktop seamlessly. And we know cool people use iTunes. You can even see the contents of the documents in the finder even if you can't possibly do anything with that file since you don't have an application installed to process it. Isn't that amazing? And we didn't yet found a way to convince game developers to consider our platform.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: I think no company had the pressure that Microsoft had. We've tried to copy Apple since day one. Bill was telling me that the first day he listened to Steve Jobs, he has figured out on his own that the GUI is the future - without any Apple inspiration. So as I've said, we've tried to copy Apple but they are moving so d**n fast. They've added attachments, we copied attachments, by the time we finished they had multitasking, we copied multitasking, they had at that point skinable interfaces, we copied that, they came up with the finder, we finally done that and they have the time machine and the cover thingie? When is this going to end? This is getting ridiculous. We still have dlls, defragmentation and registries to fix, give us a break. As I've said, the pressure is fantastic.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Okay, let's talk about backup—something everybody needs, but no one really does. Windows Backup has been around for a long time, but isn't widely used. Apple's Time Machine arrived with Leopard and deep integration with the hardware. Where are we now with OS-based backup?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Well thank you, thank you, thank you. Finally some justice! We have this really cool backup system. Is freakin amazing. You can literally destroy your Mac with a hammer after a backup, and then restore your backup on your brand new expensive Mac. Your data is there, your applications are there, you can do only partial backups, this is just cool. Neither me nor Steve don't know how is this done, but it is really cool.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Ok.... so.... Let me think a few seconds. (5 minutes later) Anyway, we have this program which is really awkward to use but we use it for marketing; it is named Previous Versions. You can still loose all your data, if your hard drive crashes, so yeah, it's pretty pointless but have no fear, you can allways use one of your 32bit or 64bit media that comes with the package to reinstall Windows and all your applications. You don't need to pay anything more, just reactivate Windows again after installation. This is what we call easy and painless. Or you can backup everything and in a matter of a few hours you can have your data stored in an external hard drive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Perhaps one of the most stressful things users face is the act of upgrading their OS. With Windows 7 coming out, people will be making choices and possibly upgrading their OS. Mr. Croll, what's Apple's perspective on what's happening with Windows 7?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Microsoft wants to milk their users of some serious cash. They've been drying for a few years now.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;:&lt;div style="color : #770000"&gt; Jay?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Well, it took us eight years to come up with this stuff and tadaa... people don't want to buy it. This... this, is unacceptable man.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;After years of integrating utilities and even full-blown apps from competing products in the operating system, or as part of the OS package, Microsoft made an about face this year and is letting end users decide whether or not they want to download Mail, Messenger, Movie Maker and other apps. Why?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: This is the reason I don't travel to Europe. Ever. EU keeps freakin sueing us, saying we're a monopoly and this and that. How would you feel paying 1.4 billion dollars to EU? I thought so. We neither. It's already hard keeping up with Apple, Linux and all the stuff that they do, but multiple competitors? Come on, this is simply unfair. And Vista didn't really sold.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Brian how do you view the debundling of applications? &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Thank God EU is not on us on this one. We already have a lot of heat on the iPod-iTunes thinge. And I can say without a doubt that what Vista's approach of debundling applications is plain stupid. I don't get why they don't keep paying 2 million euros per day like they did before.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;In the race to build the best operating system, where do each of you think you stand? What sets you apart?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Well a thing I can say for sure that we really don't have games. One or two titles, but that's pretty much it. On the other hand we don't have Registry, DLLs, activation, defragmentation, viruses, etc. Another thing is that we tried and failed several times to enter the server market.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: So what? We have registries, we have DLLs, and so what? We know they suck, but do you really had to bring them up? And let's not forget we also have this Previous Versions software where you can backup your DLLs, so it's not DLL Hell (TM) anymore; we improved this by a factor of ten so we name it DLL Hell XP (TM). XP is from eXPerience since we have over 15 years of DLLs and registries experience. And let's not forget, we don't talk about it. Very important. Plus we all know Apple is way too expensive. If I want a toaster I buy a toaster not a Ferarri that can also toast bread.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;What about Mr. Croll's activation and technology comments?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Ups, it seems I've skipped this one, heh heh... We use the activation mechanism to be sure you don't have a pirated copy of Windows, or you upgrade your computer or components from it, without buying a new Windows license.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Let's talk about pricing. There are free operating systems out there, like Linux, but, as we can see from market share, free does not necessarily translate into mass-market adoption. How do the two of you see price and the OS?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: Well we believe in charging the user as much as we can. A new keyboard? 50 euros, an upgrade? 25 euros. I really think we've nailed down quite well.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: In contrast to Apple, we believe in charging the user as much as we can. You will pay 200 bucks for your bare windows, and then you need to buy an antivirus, a video editor and so on. You can either buy our software or buy directly a computer from the "mini" series with XP installed on it in the same price range.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Okay, here's your opportunity to make your case for your OS. Mr. Paulus, why Windows?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Well we're changing the game since XP has launched. Every seven years or so we release a game changer version that offers our latest additions to keep up with Macs. And since Macs are simple, Windows 7 was also designed to be simple. So if it would be for me to sum it up in only one word, that would be it: Game Changer.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff (Question)&lt;/b&gt;: &lt;div style="color : #770000"&gt;Brian?&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Brian Coll (Apple)&lt;/b&gt;: We've bundled more applications, and we've tied it with the iPhone since we want the industry to move forward. We've decided to do tiny upgrades and rebrand them with flashy names and tax them with flashy prices. If you look at what version we had ten years behind you will see real improvements and the thousand dollars price tags worth it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lance Ulanoff&lt;/b&gt;: &lt;div style="color : #770000"&gt;Thanks for your time guys, and have fun in the future.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8008190926727437295?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8008190926727437295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8008190926727437295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8008190926727437295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8008190926727437295'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/10/windows-7-vs-mac-snow-leopard-great.html' title='Windows 7 vs. Mac Snow Leopard: The Great Debate (translated)'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-60994678634255269</id><published>2009-10-19T04:47:00.000-07:00</published><updated>2009-10-20T01:19:20.725-07:00</updated><title type='text'>Why in The End All Software Will Be Opensource, and Eventually GPL.</title><content type='html'>On 16th of March, 1953 a man was born that was going to change the software industry as we know it: his name was Richard Stallman and he is the creator of the GNU operating system. He envisioned that software should not be necessarily free of charge, but free to change, and distribute the changes, while enforcing these rules downstream so no one could block the availability of sources and the possibility of changing them.&lt;br /&gt;&lt;br /&gt;What few people know is that opensource existed long before - long in computer time - by the time Stallman decided in 1983 to start building his own operating system, Berkeley University has built and was distributing its own operating system called BSD since 1977.&lt;br /&gt;&lt;br /&gt;Stallman believed that the approach BSD was taking was a faulty one, since it allowed other vendors to simply change and repackage BSD, without giving the rights to change it further down the line.&lt;br /&gt;&lt;br /&gt;Fast forward through time, in 1990s the Free Software Foundation (FSF, the foundation that Stallman created in order to achieve the goal of a free operating system) was pretty much stuck in trying to develop a very advanced from an architectural point of view kernel. Here is where Linus Torvalds jumped in and developed his own kernel, less advanced at that point, but it worked.&lt;br /&gt;&lt;br /&gt;Fast forward even more, the GNU operating system with the Linux kernel (GNU/Linux) became widely used for servers since it was way cheaper than its UNIXes counterparts. Even more forwarding, and Linux enters also the desktop market, and while initially looking horrible, managed to compete and even bypass other graphical user interfaces (GUI).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Current State of Software&lt;/b&gt;&lt;br /&gt;Several companies learned from the momentum that GPL has created. Among them RedHat, SuSE (later bought by Novell), and later Ubuntu, and more important IBM and Google.&lt;br /&gt;&lt;br /&gt;But their motives are not similar at all as the ones of Stallman. Truth be told, no money making company believes in being altruistic at all, everything is measured in a cost/benefit analisys - this is why Microsoft until recent years had no connection with the opensource world at all, and even now they have a double personality (also known as schizophrenia) when it comes to free/opensource software. Yes, they don't believe in being altruistic even if they say so.&lt;br /&gt;&lt;br /&gt;Most companies know that the biggest expenses come not from writing the software - writing the software is actually cheap, but from testing it, and patching it. Thus it is cheaper for them to release the software opensource, even if some of the people will use it for free, since these guys will also test their product and do bug fixes for them.&lt;br /&gt;&lt;br /&gt;GPL/opensource has these major advantages over the closed source software:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;As a last resort, if the company that developed your software dies you can use the source (Luke).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can create an ecosystem around your software platform that will drive to you customers, and it will be used as means of promoting your product.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can start challenge the big ones - examples here abound: RedHat with their server families, Ubuntu with their desktop platform, Google with Android phones, the now defunct MySQL with their database, IBM with Eclipse, etc. etc.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can cut down the costs by using software for free (as in also gratis) - full software stacks being available LAMP (Linux, Apache, MySQL, PHP), many JEE solutions, file servers, desktops, etc.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This changed the game of software development quite a bit. The competition went through the roof, and pushed technological advancements in areas where the closed source was the only established answer.&lt;br /&gt;&lt;br /&gt;One last notable example is the example of Microsoft for which it took 7 years (some might say even more since Vista it's quite crappy) to release an upgrade from their XP line of desktops to Vista. Even Microsoft is slowly moving to opensource by creating its own license which is actually OSI approved.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Canonical with their&lt;/i&gt; Ubuntu &lt;i&gt;promise&lt;/i&gt; made an interesting call by deciding to respect all the freedoms of the users. Their surge in adoption I think it reflects exactly that, since this is what I call being Customer Centered - (customer centered it's a fancy term that major corporations use in order to show that they care mostly about their clients).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Of course, you can disagree with me, and of course I'm biased. In this article I just tried to show a quick history on how GPL and GNU changed the face of software. And I'm going to leave you with these screenshots over time of various operating systems to let you decide who do you think innovated most and was most consistent in improving their software over time:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A Little Bit of History&lt;/b&gt;&lt;br /&gt;&lt;h2&gt;1992-1993&lt;/h2&gt;&lt;br /&gt;Linux&lt;br/&gt;&lt;br /&gt;No desktop version available (except maybe some very ugly ones).&lt;p/&gt;&lt;br /&gt;&lt;br /&gt;Windows 3.1&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxSOePe8II/AAAAAAAAAFo/9EHQkfSXyuI/s1600-h/Windows_3.11_workspace.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxSOePe8II/AAAAAAAAAFo/9EHQkfSXyuI/s400/Windows_3.11_workspace.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394276862272663682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;NeXT (Apple)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxSVFZwBuI/AAAAAAAAAFw/Rr6yeG8nl_w/s1600-h/NeXTSTEP_desktop.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 312px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxSVFZwBuI/AAAAAAAAAFw/Rr6yeG8nl_w/s400/NeXTSTEP_desktop.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5394276975863924450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;1995-1996&lt;/h2&gt;&lt;br /&gt;Linux (KDE 1.0)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ie5BPcoUm-I/StxS7eOxgLI/AAAAAAAAAF4/Rdqhi1SVwP4/s1600-h/KDE_1.0.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_ie5BPcoUm-I/StxS7eOxgLI/AAAAAAAAAF4/Rdqhi1SVwP4/s400/KDE_1.0.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5394277635363799218" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Windows (Windows 95)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxTGklTYAI/AAAAAAAAAGA/ZChSYObNT48/s1600-h/windows95.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxTGklTYAI/AAAAAAAAAGA/ZChSYObNT48/s400/windows95.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394277826047467522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Apple&lt;br&gt;&lt;br /&gt;Nothing new.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2001-2002&lt;/h2&gt;&lt;br /&gt;Linux (KDE 2.0)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxT6pDTuKI/AAAAAAAAAGQ/uxaLoyf3E_8/s1600-h/KDE-2.0-es-es.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxT6pDTuKI/AAAAAAAAAGQ/uxaLoyf3E_8/s400/KDE-2.0-es-es.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394278720600258722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Windows (XP)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUHfPSKiI/AAAAAAAAAGY/cB_V8h6EsoA/s1600-h/winxppro.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUHfPSKiI/AAAAAAAAAGY/cB_V8h6EsoA/s400/winxppro.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394278941304433186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Apple (Leopard is out: Roarrr)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUQVOyQPI/AAAAAAAAAGg/cSVRS93fJfI/s1600-h/Macosxpb.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUQVOyQPI/AAAAAAAAAGg/cSVRS93fJfI/s400/Macosxpb.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394279093236809970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2005&lt;/h2&gt;&lt;br /&gt;Linux (KDE 3.0)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxTUerwPgI/AAAAAAAAAGI/jdR0-BDx0ko/s1600-h/Kde-3.2.3-es-es.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/StxTUerwPgI/AAAAAAAAAGI/jdR0-BDx0ko/s400/Kde-3.2.3-es-es.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394278064982081026" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Windows&lt;br/&gt;&lt;br /&gt;Nothing new for the next few years.&lt;p/&gt;&lt;br /&gt;&lt;br /&gt;Apple&lt;br/&gt;&lt;br /&gt;Nothing new.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;2009 (today)&lt;/h2&gt;&lt;br /&gt;Linux (KDE 4.0)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxUdwvd09I/AAAAAAAAAGo/vdMlAPZSvuM/s1600-h/desktop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxUdwvd09I/AAAAAAAAAGo/vdMlAPZSvuM/s400/desktop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394279323959940050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Windows (Vista)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxUktVmcVI/AAAAAAAAAGw/GrWsErewERk/s1600-h/vista_desktop.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/StxUktVmcVI/AAAAAAAAAGw/GrWsErewERk/s400/vista_desktop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394279443305230674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Apple (Snow Leopard)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUrm_NelI/AAAAAAAAAG4/9zY4KSWQyzA/s1600-h/leopard_xp_os_x_visual_style_by_cydonaireproductions_z.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 320px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/StxUrm_NelI/AAAAAAAAAG4/9zY4KSWQyzA/s400/leopard_xp_os_x_visual_style_by_cydonaireproductions_z.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5394279561859791442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-60994678634255269?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/60994678634255269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=60994678634255269' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/60994678634255269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/60994678634255269'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/10/why-in-end-all-software-will-be.html' title='Why in The End All Software Will Be Opensource, and Eventually GPL.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ie5BPcoUm-I/StxSOePe8II/AAAAAAAAAFo/9EHQkfSXyuI/s72-c/Windows_3.11_workspace.png' height='72' width='72'/><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4483838024934130456</id><published>2009-10-06T17:22:00.001-07:00</published><updated>2009-10-06T17:27:11.978-07:00</updated><title type='text'>Windows is HOT.</title><content type='html'>Who said that windows is lame?&lt;br /&gt;&lt;br /&gt;Windows can be really hot:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/Ssvfb5pdYdI/AAAAAAAAAFg/OUmE9-aHdKQ/s1600-h/kde4.3-windows-3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 232px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/Ssvfb5pdYdI/AAAAAAAAAFg/OUmE9-aHdKQ/s400/kde4.3-windows-3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5389647049503105490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Of course, this is KDE 4.3 with some plasmoids running on top of a Windows XP.&lt;br /&gt;&lt;br /&gt;All that it remains is for Windows to fully change its shell and taskbar with the KDE one, so at least it might look like a decent operating system - for now we'll ignore what's under the hood.&lt;br /&gt;&lt;br /&gt;KDE 4.3 team, you've outdone yourself. Great job!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4483838024934130456?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4483838024934130456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4483838024934130456' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4483838024934130456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4483838024934130456'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/10/windows-is-hot.html' title='Windows is HOT.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ie5BPcoUm-I/Ssvfb5pdYdI/AAAAAAAAAFg/OUmE9-aHdKQ/s72-c/kde4.3-windows-3.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4238447782184135570</id><published>2009-09-04T07:39:00.000-07:00</published><updated>2009-09-04T07:44:43.662-07:00</updated><title type='text'>AndroidKnight Presentation Video</title><content type='html'>In these two videos I'm explaining some functional design decisions that were made when developing &lt;a href="http://androidknight.com"&gt;AndroidKnight&lt;/a&gt;, and what makes AndroidKnight one of the best chess games you'll find on a mobile phone.&lt;br /&gt;&lt;br /&gt;I want to apologize for the video quality, but since this is my first video online, I know you'll be forgiving.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Part 1&lt;/h3&gt;&lt;br /&gt;&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rFaVGHmVX5I&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/rFaVGHmVX5I&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Part 2&lt;/h3&gt;&lt;br /&gt;&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/dZCU2qOv1i0&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/dZCU2qOv1i0&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4238447782184135570?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4238447782184135570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4238447782184135570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4238447782184135570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4238447782184135570'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/09/androidknight-presentation-video.html' title='AndroidKnight Presentation Video'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7464185483618793337</id><published>2009-09-02T18:32:00.000-07:00</published><updated>2009-09-02T18:48:23.085-07:00</updated><title type='text'>No need to wait. AndroidKnight is there.</title><content type='html'>Hi, I can finally say it:&lt;br /&gt;&lt;br /&gt;"It is done"&lt;br /&gt;&lt;br /&gt;Version 1.0.3 of my AndroidKnight (written actually as): &lt;p/&gt;&lt;a href="http://androidknight.com"&gt;&lt;div style="font-size : 20px;"&gt;&lt;div style="float : left; font-size : 10px"&gt;Android&lt;/div&gt;Knight&lt;/div&gt;&lt;/a&gt; &lt;br/&gt;is finally finished and published on the Android Market. This is my entry for the adc2 (Android Developer Contest 2).&lt;br /&gt;&lt;br /&gt;It's website is of course &lt;a href="http://androidknight.com"&gt;androidknight.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You may ask: where are the sources? Don't worry, they're arriving. And they will be GPL3.&lt;br /&gt;&lt;br /&gt;Some screenshots to get you going:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8eblJs8cI/AAAAAAAAAE4/hSsDf3tHykM/s1600-h/androidknight7.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8eblJs8cI/AAAAAAAAAE4/hSsDf3tHykM/s400/androidknight7.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5377049939281768898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ie5BPcoUm-I/Sp8eu5McmRI/AAAAAAAAAFY/gltQW26TBe8/s1600-h/androidknight14.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://1.bp.blogspot.com/_ie5BPcoUm-I/Sp8eu5McmRI/AAAAAAAAAFY/gltQW26TBe8/s400/androidknight14.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5377050271079504146" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8er5XbRHI/AAAAAAAAAFQ/Fyk1J_iqKts/s1600-h/androidknight13.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8er5XbRHI/AAAAAAAAAFQ/Fyk1J_iqKts/s400/androidknight13.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5377050219585946738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8enoi0K7I/AAAAAAAAAFI/bpr9MhYDPNA/s1600-h/androidknight12.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8enoi0K7I/AAAAAAAAAFI/bpr9MhYDPNA/s400/androidknight12.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5377050146350836658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8ehry498I/AAAAAAAAAFA/ZNB5wGYgxMs/s1600-h/androidknight8.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 308px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8ehry498I/AAAAAAAAAFA/ZNB5wGYgxMs/s400/androidknight8.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5377050044144351170" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7464185483618793337?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7464185483618793337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7464185483618793337' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7464185483618793337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7464185483618793337'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/09/no-need-to-wait-androidknight-is-there.html' title='No need to wait. AndroidKnight is there.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/Sp8eblJs8cI/AAAAAAAAAE4/hSsDf3tHykM/s72-c/androidknight7.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7709361834686373828</id><published>2009-07-10T07:06:00.000-07:00</published><updated>2009-07-10T07:07:05.510-07:00</updated><title type='text'>Linux FTW</title><content type='html'>I can not imagine doing development without Linux.&lt;br /&gt;&lt;br /&gt;I don't get how people can live without multiple desktops (even on multiple screens they are a must), without a decent terminal (tabs and bash), or a decent window manager (at least expose, and "allways on top" for a certain window).&lt;br /&gt;&lt;br /&gt;And here comes the fun part: I am in a Microsoft Gold certified company. I am using of course Linux (Ubuntu). Our customer uses RedHat Linux, and a JEE stack (JBoss). At home I have another Ubuntu box.&lt;br /&gt;&lt;br /&gt;Recently I've bought a g1 (google Android), and now my phone also runs Linux.&lt;br /&gt;&lt;br /&gt;Or as Mahatma Ghandi used to say: "And then you win".&lt;br /&gt;&lt;br /&gt;Thank you Stallman.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7709361834686373828?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7709361834686373828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7709361834686373828' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7709361834686373828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7709361834686373828'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/07/linux-ftw.html' title='Linux FTW'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6383065150841447278</id><published>2009-05-22T00:28:00.000-07:00</published><updated>2009-05-22T09:13:45.817-07:00</updated><title type='text'>svn real revert</title><content type='html'>Sometimes it happens that we screw up our code in some file. And we want to go to some previous version of that specific file, hoping in our blind faith in source control versioning.&lt;br /&gt;&lt;br /&gt;I don't know how many of you are still using SVN, and not Mercurial. If you do use SVN, you most likely have been fooled at least once by:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;svn update -r oldrev path/to/file/to/change&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The problem with this is that when you do update to a revision that is from the past, SVN still remember this, and on the next update &amp;&amp; commit combo, you will yet again have the newer version of the file.&lt;br /&gt;&lt;br /&gt;Thus a better way would be to just reapply the changes, but in the opposite order, without SVNs intervention. What we need is to create a patch from the new version back to the old version, and apply that one to the file.&lt;br /&gt;&lt;br /&gt;What many people might not know, is that SVN actually knows how to do create patches between any revisions (not only in ascending way - e.g. from the oldrev to the newrev) including from a newer version to an older one. &lt;br /&gt;&lt;br /&gt;So I will ask SVN to do a patch from the new revision to the old revision, and I will apply it directly using the patch command like so:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;svn diff -r newrev:oldrev path/to/file/to/change | patch -p1&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And by this, we do have the guarantee that only the changes are set into the file, without SVN changing the version of the file.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;&lt;br /&gt;Looks like the best way to do this, is to use svn merge, which will do also the patching, so the need for the patch command is unnecessary.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;svn merge -r HEAD:oldrev path/to/file&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Thank you &lt;a href="http://blog.technostoic.net/"&gt;rpetre&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6383065150841447278?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6383065150841447278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6383065150841447278' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6383065150841447278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6383065150841447278'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/05/svn-real-revert.html' title='svn real revert'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-3711954314205005368</id><published>2009-04-25T18:46:00.000-07:00</published><updated>2009-05-24T19:14:06.135-07:00</updated><title type='text'>Test Driven Development, How To?</title><content type='html'>In software there are a lot of methodologies on how to implement software, but really few reduce greatly the time of development or really simplify it.&lt;br /&gt;&lt;br /&gt;Most programmers probably know, but even if you don't know, it is good to notice: the great bulk of time in development of a software is spent in bug fixing and maintainance. They can take from 55% in most lucky projects, to around 95%.&lt;br /&gt;&lt;br /&gt;The time spent in bug fixing relies mostly on how much you decide to invest in it also. For example having 95% of time used on bug-fixing could mean that the software product emphasizes a great level of quality. For this scenario consider for example a real-time device programming, or an air traffic control software. The later one needs to be stable for years to come, and have minimal downtime.&lt;br /&gt;&lt;br /&gt;In desktop programming around 75% of the time is bug fixing. Why does software spends between two thirds to three quarters doing bug fixing instead adding features? Well, last time I've checked, developers were still humans, and they can only keep a limited amount of ideas in parallel; but since they have to focus on memory management, performance, writing useful code, interaction between components, specifications, etc. this will overwhelm quite easily even the best developers.&lt;br /&gt;&lt;br /&gt;Test Driven Development (TDD) is a software methodology created to reduce the time of staying in bug fixing "mode". The best qualities of it are:&lt;ul&gt;&lt;br /&gt;&lt;li&gt; detect bugs as early as possible&lt;/li&gt;&lt;br /&gt;&lt;li&gt; has several tests that have input scenarios for the software, and expect some output.&lt;/li&gt;&lt;br /&gt;&lt;li&gt; makes the code to trigger feedbacks to the developer if something wrong happens, before a QA analysis. or in the much worse case, a user noticing it.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Which are the steps to do TDD?&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;since it is named &lt;i&gt;test driven&lt;/i&gt;, you should &lt;b&gt;write your tests first, before you write the code&lt;/b&gt;. Or if the code exists, make tests to reflect the interface (without assuming the implementation is even better).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;make your tests pass&lt;/b&gt; with minimal code in the implementation side.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;refactor your code&lt;/b&gt; to be as good as you want, as long as it doesn't break the tests&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As an example let's say that your application uses nUnit framework to do the unit tests, which are small programs that define a collection of tests.&lt;br /&gt;&lt;br /&gt;Here is a test that checks in a &lt;a href="http://narocad.blogspot.com/"&gt;real world application&lt;/a&gt; if one document has a right working Undo function:&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid black; font-family: monospace; font-size: 10px;"&gt;&lt;span style="color:#a52a2a;"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color:#a52a2a;"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/span&gt; NUnit.Framework;&lt;br /&gt;&lt;span style="color:#a52a2a;"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/span&gt; TreeData.AttributeInterpreter;&lt;br /&gt;&lt;span style="color:#a52a2a;"&gt;&lt;b&gt;using&lt;/b&gt;&lt;/span&gt; TreeData.NaroData;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;namespace&lt;/b&gt;&lt;/span&gt; NaroTestSuite.TreeData&lt;br /&gt;{&lt;br /&gt;[TestFixture]&lt;br /&gt;&lt;span style="color:#2e8b57;"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt; UndoRedoTests&lt;br /&gt;{&lt;br /&gt;    [Test]&lt;br /&gt;    &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#2e8b57;"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/span&gt; UndoAppliedEmpty()&lt;br /&gt;    {&lt;br /&gt;        DefaultInterpreters.Setup();&lt;br /&gt;        Document doc = &lt;span style="color:#a52a2a;"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt; Document();&lt;br /&gt;        Assert.AreEqual(&lt;span style="color:#ff00ff;"&gt;0&lt;/span&gt;, doc.Root.Interpreters.Count); &lt;span style="color:#0000ff;"&gt;// assert 1&lt;/span&gt;&lt;br /&gt;        doc.Transact();&lt;br /&gt;        doc.Root.Update&amp;lt;IntegerInterpreter&amp;gt;().Value = &lt;span style="color:#ff00ff;"&gt;2&lt;/span&gt;;&lt;br /&gt;        Assert.AreEqual(&lt;span style="color:#ff00ff;"&gt;1&lt;/span&gt;, doc.Root.Interpreters.Count); &lt;span style="color:#0000ff;"&gt;// assert 2&lt;/span&gt;&lt;br /&gt;        doc.Commit();&lt;br /&gt;        Assert.AreEqual(&lt;span style="color:#ff00ff;"&gt;1&lt;/span&gt;, doc.Root.Interpreters.Count); &lt;span style="color:#0000ff;"&gt;// assert 3 &lt;/span&gt;&lt;br /&gt;        doc.Undo();&lt;br /&gt;        Assert.AreEqual(&lt;span style="color:#ff00ff;"&gt;0&lt;/span&gt;, doc.Root.Interpreters.Count); &lt;span style="color:#0000ff;"&gt;// assert 4&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It is easy to write tests? Well, you need to define your expectations (or assertions) - things that you believe to hold true. Here are the normal expectations for a class that store a document in a doc.Root tree data (from the example above):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;a newly created document is an empty one and an empty document will have no attributes (assert 1)&lt;/li&gt;&lt;li&gt;after I will add an integer attribute the attribute count should increase with 1 (assert 2)&lt;/li&gt;&lt;li&gt;after I will try to save the status of the document (after a "commit") the document should not change the attribute count (assert 3)&lt;/li&gt;&lt;li&gt;after I do an Undo, the document will decrease to original document count, so it will be zero (assert 4)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Making tests first will do a very important thing for the developer, it will give to it concrete cases how the actual implementation classes (the tested ones) are used and this means real documentation. Also, using a tested class and if the specified class has the tests passing, will mean that some problem is actually coming from another part of the application, or from an incorrect usage of that class in the production code. This inherently removes a lot of assumptions about what breaks and why.&lt;br /&gt;&lt;br /&gt;A great thing also is that tests are often much smaller than the entire application. So debugging it will reduce to debugging of the latest usage of the document, is not the entire application that may not work with Undo function.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How about regression testing?&lt;/b&gt;&lt;br /&gt;Regression Testing (RT) is almost the same as TDD but is done after application is written (for instance to an user), there is a test written "to not happen again". RT has some downsides:&lt;br /&gt;- the developer (or QA) who writes the test can get the application architecture. This may mean that we can create a test to pass our code, instead our code to pass our tests&lt;br /&gt;- at development time, there are no tests to check if a component is working (excluding the developer will debug the program again and again)&lt;br /&gt;&lt;br /&gt;Should you use RT? Yes, definetly! RT appears in ways that application you have never expected to crash or to run, does so, and where you don't want it. Also, the user bugs are great to be tracked. A flawed component will most probably crash again. There is a &lt;a href="http://www.youtube.com/watch?v=zXRxsRgLRZ4"&gt;QA 80/20 theory&lt;/a&gt; which says: 80% of errors are in 20% of code. TDD will say that for your cases your code will work correctly. But still there are your tests, which may not reflect the real life cases.&lt;br /&gt;&lt;br /&gt;As in our example: who creates a single document to store only one integer in it?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;We've shown several steps on how to implement TDD, we've been over a minor test case, and we've outlined several advantages of using TDD. We've did a short comparison of TDD with RT.&lt;br /&gt;&lt;br /&gt;I hope this will stir your appetite for TDD at least as we're having it here at freeopenidea.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-3711954314205005368?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/3711954314205005368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=3711954314205005368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3711954314205005368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3711954314205005368'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/04/test-driven-development-how-to.html' title='Test Driven Development, How To?'/><author><name>ciplogic</name><uri>http://www.blogger.com/profile/05409605028353356569</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-921703842813419839</id><published>2009-04-23T10:20:00.000-07:00</published><updated>2009-04-23T10:47:28.512-07:00</updated><title type='text'>Major facelift on freeopenidea.blogspot.com</title><content type='html'>As you can see, this blog it's looking now much more nicely. This happened since I got some spare time, and also because of the following opensource/free tools:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gimp.org/"&gt;gimp&lt;/a&gt; and &lt;a href="http://www.mozilla.com/en-US/firefox/"&gt;firefox&lt;/a&gt; (with &lt;a href="http://getfirebug.com/"&gt;firebug&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;And of course, my mighty operating system: &lt;a href="http://www.ubuntu.com/"&gt;ubuntu&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-921703842813419839?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/921703842813419839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=921703842813419839' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/921703842813419839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/921703842813419839'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/04/major-facelift-on-freeopenideablogspotc.html' title='Major facelift on freeopenidea.blogspot.com'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6370343099811455932</id><published>2009-04-10T12:54:00.000-07:00</published><updated>2009-04-10T13:14:30.338-07:00</updated><title type='text'>MagicGroup 1.2.0 is out</title><content type='html'>It makes me great pleasure to announce you that MagicGroup 1.2.0 is out.&lt;br /&gt;&lt;br /&gt;MagicGroup is a plugin for Eclipse that allows you to group the files you're working on, in a logical way. A longer description of it, you can find in &lt;a href="http://freeopenidea.blogspot.com/2008/06/beauty-of-opensource.html"&gt;a previous post of mine&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The changes are:&lt;br /&gt;1. Mercurial source code is available on sf.net. Of course, it is EPL and GPL3.&lt;br /&gt;2. MigLayout is now used for the popup used for renaming and creating groups.&lt;br /&gt;&lt;br /&gt;Here is a quick "before and after" using MigLayout:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sd-lIlkgvJI/AAAAAAAAAEo/Wk4QP349IPs/s1600-h/before.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 299px; height: 167px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sd-lIlkgvJI/AAAAAAAAAEo/Wk4QP349IPs/s400/before.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323154851518004370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;center&gt;&lt;b&gt;Before&lt;/b&gt;&lt;p/&gt; and &lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sd-lZwIXG5I/AAAAAAAAAEw/XJOJKfDGU5c/s1600-h/after.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 147px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/Sd-lZwIXG5I/AAAAAAAAAEw/XJOJKfDGU5c/s400/after.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323155146410498962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;center&gt;&lt;b&gt;After&lt;/b&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The plugin is available for download here:&lt;br /&gt;&lt;a href="https://sourceforge.net/project/showfiles.php?group_id=224162&amp;package_id=271060&amp;release_id=674924"&gt;https://sourceforge.net/project/showfiles.php?group_id=224162&amp;package_id=271060&amp;release_id=674924&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Have fun.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6370343099811455932?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6370343099811455932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6370343099811455932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6370343099811455932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6370343099811455932'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/04/magicgroup-120-is-out.html' title='MagicGroup 1.2.0 is out'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/Sd-lIlkgvJI/AAAAAAAAAEo/Wk4QP349IPs/s72-c/before.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7788737111220217062</id><published>2009-04-08T06:57:00.000-07:00</published><updated>2009-04-08T07:17:18.245-07:00</updated><title type='text'>PostgreSQL bad practices</title><content type='html'>I was reading the "Tip of the Day" in pgadmin3, when I found this gem:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;It is good practice to build application logic into the database itself by using functions and views. This ensures that different front-ends to your products will always see the same views of data and update and modify data in the same way. Better yet, you only have to write it all once for all front-ends!&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;While the sentence itself, does have some truth it it, in my opinion is misleading. I don't think it's good practice, but rather bad practice. I don't deny that there can be valid, performance related reasons to actually use functions and views (my big problem is with functions, not views, since views are pretty standardized) in the database, but let's be honest: the moment that you have stored procedures in the DB you are married to that vendor of the DB.&lt;br /&gt;&lt;br /&gt;Be that vendor PostgreSQL, or even Oracle, it's obviously the same thing; and it's not good practice to be tied to a vendor.&lt;br /&gt;&lt;br /&gt;Another issue that I have against this, is that you actually split your business logic into several places. While this doesn't fully invalidate the DRY principle (Don't Repeat Yourself), since really, you don't repeat yourself, it has a sneakier drawback:&lt;br /&gt;&lt;br /&gt;Your logic is not found anymore in only one place, but rather divided over different (and most of the time totally different) places (and architectures). It can even be 2 different machines. This alone can make debugging a really tough time.&lt;br /&gt;&lt;br /&gt;Thus I find approaches like Hibernate Validators much more enjoyable for the same task. You have your constraints and business logic over the domain in only one place. They can't do complex DB operations, but I think most of the time this can be resolved via Object Oriented programming and some nice services.&lt;br /&gt;&lt;br /&gt;As people on the Internet tend to get really heated, I want to outline this again: I'm not saying that stored procedures have no place in an application.&lt;br /&gt;&lt;br /&gt;What I am saying though, is that you should be really careful when adding them in the application in the first place. I would go and argument that encapsulating them in a service, that is a wrapper over the stored procedure, so at any given time later to be able to change it for a different DB would be a nice approach.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;Here are my 2 cents regarding the previous Tip of the Day:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Don't get tied to a single vendor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Keep your business domain in a single place.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Have clear boundaries on the stored procedure call, to be able to replace it, if you can't live without it.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7788737111220217062?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7788737111220217062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7788737111220217062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7788737111220217062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7788737111220217062'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/04/postgresql-bad-practices.html' title='PostgreSQL bad practices'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5345094331549723995</id><published>2009-03-27T08:53:00.000-07:00</published><updated>2009-03-27T10:23:08.538-07:00</updated><title type='text'>I'm a hacker... NOT</title><content type='html'>Recently I had the pleasure to navigate through &lt;a href="http://milw0rm.com/"&gt;milw0rm&lt;/a&gt;'s exploits. A lot of them are pretty much &lt;a href="http://en.wikipedia.org/wiki/Kryptonite"&gt;kryptonite&lt;/a&gt; for me, but I think this (milw0rm) is a great place to learn more about security and expand general knowledge about how the exploit works... with more of a "hands on" approach, then security by obscurity promoted by &lt;a href="http://microsoft.com"&gt;some weird companies&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Until I found &lt;a href="http://milw0rm.com/exploits/7842"&gt;this "exploit"&lt;/a&gt;. It supposed to be some sort of a bug for Firefox 3.0.5, and exposed as "Firefox 3.0.5 Status Bar Obfuscation / Clickjacking".&lt;br /&gt;&lt;br /&gt;Let's get a few things straight. Almost all recent browsers represent the page internally under a structure called &lt;a href="http://en.wikipedia.org/wiki/Document_Object_Model"&gt;Document Object Model&lt;/a&gt; (DOM). The defacto programming language, that again, almost all recent browsers implement, is ECMAScript, better known under the name of JavaScript.&lt;br /&gt;&lt;br /&gt;JavaScript code that runs inside the browser can access the DOM and modify the DOM in almost every imaginable way - actually because of this extreme flexibility the whole Web 2.0 concept was born out.&lt;br /&gt;&lt;br /&gt;Back to the main topic. If you have code like this (taken from the "exploit"):&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;25 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;href&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;a href="http://www.google.com"&gt;http://www.google.com&lt;/a&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;onclick=&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;updatebox&lt;/font&gt;(&lt;font color="#a52a2a"&gt;&lt;b&gt;event&lt;/b&gt;&lt;/font&gt;)&lt;font color="#6a5acd"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;font&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;26 &lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;style&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;font-family:arial;font-size:32px&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&lt;u&gt;&lt;a href="http://www.google.com"&gt;http://www.google.com&lt;/a&gt;&lt;/u&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;font&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;br&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;that calls a function like this:&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;&lt;font color="#008b8b"&gt;function&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;updatebox&lt;/font&gt;(&lt;font color="#6a5acd"&gt;evt&lt;/font&gt;)&lt;font color="#6a5acd"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&lt;font color="#6a5acd"&gt;mouseX=evt.pageX?evt.pageX:evt.clientX;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&lt;font color="#6a5acd"&gt;mouseY=evt.pageY?evt.pageY:evt.clientY;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;document&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;.getElementById&lt;/font&gt;(&lt;font color="#ff00ff"&gt;'mydiv'&lt;/font&gt;)&lt;font color="#6a5acd"&gt;.style.left=mouseX&lt;/font&gt;-1&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;document&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;.getElementById&lt;/font&gt;(&lt;font color="#ff00ff"&gt;'mydiv'&lt;/font&gt;)&lt;font color="#6a5acd"&gt;.style.&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;top&lt;/b&gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;=mouseY&lt;/font&gt;-1&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;12 &lt;/font&gt;&lt;font color="#008b8b"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;13 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;then please don't say it's an exploit, just say it's expected functionality from any decent browser that has JavaScript enabled.&lt;br /&gt;&lt;br /&gt;Notice the DOM manipulation right there: document.getElementById('mydiv').style.left=mouseX-1;&lt;br /&gt;&lt;br /&gt;And since we can do DOM manipulations, there's no need to move divs around for the "clickjacking". We can just change the href's target and that's it:&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;3 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;body&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;4 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;language&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;JavaScript&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;5 &lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008b8b"&gt;function&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;navigate&lt;/font&gt;(&lt;font color="#6a5acd"&gt;element&lt;/font&gt;)&lt;font color="#6a5acd"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;element.href = &lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;a href="http://milw0rm.com"&gt;http://milw0rm.com&lt;/a&gt;&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008b8b"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;script&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Valid link:&lt;br /&gt;&lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#6a5acd"&gt;onclick=&amp;quot;&lt;/font&gt;&lt;font color="#6a5acd"&gt;navigate&lt;/font&gt;(&lt;font color="#008b8b"&gt;this&lt;/font&gt;)&lt;font color="#6a5acd"&gt;;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;href&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;=&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;a href="http://www.google.com"&gt;http://www.google.com&lt;/a&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;font color="#6a5acd"&gt;&lt;u&gt;www.google.com&lt;/u&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;a&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;12 &lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;body&lt;/b&gt;&lt;/font&gt;&lt;font color="#008b8b"&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;On a funny note: Hey, this code it's even cross browser!! It also works on several other browsers. Thus I give you: "Firefox/Opera/Safari/IE/... Status Bar Obfuscation / Clickjacking".&lt;br /&gt;&lt;br /&gt;&lt;script language="JavaScript"&gt;function navigate(element) { element.href = "http://www.shibumi.org/eoti.htm"; } &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;You could visit &lt;a onclick="navigate(this)" href="http://google.com/"&gt;google.com&lt;/a&gt; for more information. :P&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5345094331549723995?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5345094331549723995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5345094331549723995' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5345094331549723995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5345094331549723995'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/03/im-hacker-not.html' title='I&apos;m a hacker... NOT'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-2581611652232504128</id><published>2009-03-25T03:20:00.000-07:00</published><updated>2009-03-27T16:49:54.223-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='short program'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy scripting</title><content type='html'>I got lately very pissed off on svn management, especially when trying to commit. The reason behind it, is that I want to be able to pick what files to commit, also by looking at the actual changes in the files.&lt;br /&gt;&lt;br /&gt;Do you remember once that &lt;a href="http://freeopenidea.blogspot.com/2008/12/short-program-to-count-lines-of-code.html"&gt;I wasn't a very big fan of one liners&lt;/a&gt;? So... how many lines of code do you need in order to develop a real application which looks like this: &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/ScoGn8jcvAI/AAAAAAAAAEg/VR5zMgzviU4/s1600-h/Screenshot-commit-3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 140px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/ScoGn8jcvAI/AAAAAAAAAEg/VR5zMgzviU4/s200/Screenshot-commit-3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5317069593403767810" /&gt;&lt;/a&gt;&lt;br /&gt;(that does svn commit management - being a wrapper over the svn command)?&lt;br /&gt;&lt;br /&gt;The answer is... 207. (including white spaces, layouts, etc.). All that you need is groovy and MigLayout.&lt;br /&gt;&lt;br /&gt;And here goes the code:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#0000ff"&gt;#!/usr/bin/env groovy&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;net.miginfocom.swing.*&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;java.awt.event.*&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;javax.swing.*&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;javax.swing.event.*&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;javax.swing.text.*&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;java.awt.*&lt;br /&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;javax.swing.table.AbstractTableModel&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SVNRecord {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;path&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;change&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;boolean&lt;/b&gt;&lt;/font&gt;&amp;nbsp;lock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;boolean&lt;/b&gt;&lt;/font&gt;&amp;nbsp;checked&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MyTable &lt;font color="#2e8b57"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JTable {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;init()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; &lt;font color="#ff00ff"&gt;3&lt;/font&gt;; i++)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;.columnModel.getColumn(i).maxWidth = &lt;font color="#ff00ff"&gt;16&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MyTableModel &lt;font color="#2e8b57"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt;&amp;nbsp;AbstractTableModel {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;records&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;getColumnName(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;switch&lt;/b&gt;&lt;/font&gt;(column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;0&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;X&amp;quot;&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;// select it for commit&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;1&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;L&amp;quot;&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;// lock status&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;M&amp;quot;&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;// modified&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;3&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;Path&amp;quot;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Class getColumnClass(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;c)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;getValueAt(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;, c).getClass();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;getRowCount()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;records.&lt;font color="#008b8b"&gt;size&lt;/font&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;getColumnCount()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;4&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Object getValueAt(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;row, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;switch&lt;/b&gt;&lt;/font&gt;(column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;0&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;records[row].checked&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;1&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;records[row].lock&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;2&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;records[row].change&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;case&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;3&lt;/font&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;records[row].path&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;boolean&lt;/b&gt;&lt;/font&gt;&amp;nbsp;isCellEditable(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;row, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;column == &lt;font color="#ff00ff"&gt;0&lt;/font&gt;&amp;nbsp;? &lt;font color="#ff00ff"&gt;true&lt;/font&gt;&amp;nbsp;: &lt;font color="#ff00ff"&gt;false&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;setValueAt(Object value, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;row, &lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;column)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;records[row].checked = value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;.metaClass.system = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Runtime().exec([&lt;font color="#ff00ff"&gt;&amp;quot;/bin/bash&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;-c&amp;quot;&lt;/font&gt;, delegate]&amp;nbsp;&lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;[]).&lt;font color="#6a5acd"&gt;in&lt;/font&gt;.text&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;records = &lt;font color="#ff00ff"&gt;null&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;JFrame wnd = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JFrame()&lt;br /&gt;wnd.title = &lt;font color="#ff00ff"&gt;&amp;quot;commit&amp;quot;&lt;/font&gt;&lt;br /&gt;wnd.defaultCloseOperation = JFrame.EXIT_ON_CLOSE&lt;br /&gt;wnd.layout = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MigLayout(&lt;font color="#ff00ff"&gt;&amp;quot;fill&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;[growprio 1][]unrelated[growprio 1][]&amp;quot;&lt;/font&gt;)&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;jtable = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MyTable()&lt;br /&gt;jtable.model = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MyTableModel()&lt;br /&gt;jtable.model.records = records&lt;br /&gt;jtable.selectionMode = ListSelectionModel.SINGLE_SELECTION&lt;br /&gt;jtable.rowSelectionAllowed = &lt;font color="#ff00ff"&gt;true&lt;/font&gt;&lt;br /&gt;jtable.columnSelectionAllowed = &lt;font color="#ff00ff"&gt;false&lt;/font&gt;&lt;br /&gt;jtable.init()&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;reloadChangedFiles = { &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;records = &lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;svn stat&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;.system().split(&amp;quot;&lt;/font&gt;\n&lt;font color="#ff00ff"&gt;&amp;quot;).findAll { line -&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;! line.startsWith(&lt;font color="#ff00ff"&gt;&amp;quot;?&amp;quot;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.&lt;font color="#008b8b"&gt;collect&lt;/font&gt;&amp;nbsp;{ line &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;m = line =~ /(.*?)\s+(.*?)\s+(.*$)/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.matches()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;record = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SVNRecord()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record.path = m.group(&lt;font color="#ff00ff"&gt;3&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record.lock = m.group(&lt;font color="#ff00ff"&gt;2&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record.change = m.group(&lt;font color="#ff00ff"&gt;1&lt;/font&gt;)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;jtable.model.records = records&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;reloadChangedFiles()&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;createPanel = { &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;JPanel result = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JPanel()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.layout = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MigLayout(&lt;font color="#ff00ff"&gt;&amp;quot;fill&amp;quot;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;result&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;JPanel leftPanel = createPanel()&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;topPanel = createPanel()&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;scroll = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JScrollPane(jtable)&lt;br /&gt;topPanel.add &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JLabel(&lt;font color="#ff00ff"&gt;&amp;quot;File List:&amp;quot;&lt;/font&gt;), &lt;font color="#ff00ff"&gt;&amp;quot;growx&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;refreshButton = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JButton(&lt;font color="#ff00ff"&gt;&amp;quot;Refresh&amp;quot;&lt;/font&gt;)&lt;br /&gt;topPanel.add refreshButton, &lt;font color="#ff00ff"&gt;&amp;quot;wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;topPanel.add scroll, &lt;font color="#ff00ff"&gt;&amp;quot;width 300::, grow, span, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;bottomPanel = createPanel()&lt;br /&gt;bottomPanel.add &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JLabel(&lt;font color="#ff00ff"&gt;&amp;quot;Diff:&amp;quot;&lt;/font&gt;), &lt;font color="#ff00ff"&gt;&amp;quot;wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;diffTextPane = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JTextPane()&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;textPaneScroll = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JScrollPane(diffTextPane)&lt;br /&gt;bottomPanel.add textPaneScroll, &lt;font color="#ff00ff"&gt;&amp;quot;width 300::, wrap, grow&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;verticalSplit = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JSplitPane(JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel)&lt;br /&gt;leftPanel.add verticalSplit, &lt;font color="#ff00ff"&gt;&amp;quot;grow, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;JPanel rightPanel = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JPanel()&lt;br /&gt;rightPanel.layout = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MigLayout(&lt;font color="#ff00ff"&gt;&amp;quot;fill, top&amp;quot;&lt;/font&gt;)&lt;br /&gt;rightPanel.add &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JLabel(&lt;font color="#ff00ff"&gt;&amp;quot;Comment:&amp;quot;&lt;/font&gt;), &lt;font color="#ff00ff"&gt;&amp;quot;top, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;commitTextPane = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JTextPane()&lt;br /&gt;rightPanel.add &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JScrollPane(commitTextPane), &lt;font color="#ff00ff"&gt;&amp;quot;growx, height 200::, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;revertButton = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JButton(&lt;font color="#ff00ff"&gt;&amp;quot;revert&amp;quot;&lt;/font&gt;)&lt;br /&gt;rightPanel.add revertButton, &lt;font color="#ff00ff"&gt;&amp;quot;growx, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;commitButton = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JButton(&lt;font color="#ff00ff"&gt;&amp;quot;commit&amp;quot;&lt;/font&gt;)&lt;br /&gt;rightPanel.add commitButton, &lt;font color="#ff00ff"&gt;&amp;quot;growx, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;closeButton = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JButton(&lt;font color="#ff00ff"&gt;&amp;quot;close&amp;quot;&lt;/font&gt;)&lt;br /&gt;rightPanel.add closeButton, &lt;font color="#ff00ff"&gt;&amp;quot;growx, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;horizontalSplit = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel)&lt;br /&gt;horizontalSplit.oneTouchExpandable = &lt;font color="#ff00ff"&gt;true&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;wnd.contentPane.add horizontalSplit, &lt;font color="#ff00ff"&gt;&amp;quot;grow, wrap&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;wnd.pack()&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;selectedIndex = -&lt;font color="#ff00ff"&gt;1&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Style textStyle = diffTextPane.addStyle(&lt;font color="#ff00ff"&gt;&amp;quot;red&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;null&lt;/font&gt;);&lt;br /&gt;StyleConstants.setForeground(textStyle, Color.RED);&lt;br /&gt;textStyle = diffTextPane.addStyle(&lt;font color="#ff00ff"&gt;&amp;quot;blue&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;null&lt;/font&gt;);&lt;br /&gt;StyleConstants.setForeground(textStyle, Color.BLACK);&lt;br /&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// actions&lt;/font&gt;&lt;br /&gt;jtable.selectionModel.addListSelectionListener({ event &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;jtable.selectedRows[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(! event.valueIsAdjusting)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;selectedIndex = jtable.selectedRows[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StyledDocument document = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;DefaultStyledDocument()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;diffText = &lt;font color="#ff00ff"&gt;&amp;quot;svn diff &lt;/font&gt;&lt;font color="#008b8b"&gt;${records[selectedIndex].path}&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;.system()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;document.insertString(document.endPosition.offset, diffText, &lt;font color="#ff00ff"&gt;null&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diffTextPane.document = document&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;} &lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;ListSelectionListener)&lt;br /&gt;&lt;br /&gt;revertButton.addActionListener({ event &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;svn revert ${records[selectedIndex].path}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;.system()&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;records.remove(selectedIndex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;jtable.revalidate()&lt;br /&gt;} &lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;ActionListener)&lt;br /&gt;&lt;br /&gt;closeButton.addActionListener({ event &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.exit(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;)&lt;br /&gt;} &lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;ActionListener)&lt;br /&gt;&lt;br /&gt;commitButton.addActionListener({ event &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;fileList = records.&lt;font color="#008b8b"&gt;findAll&lt;/font&gt;&amp;nbsp;{ record &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record.checked&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.&lt;font color="#008b8b"&gt;collect&lt;/font&gt;&amp;nbsp;{ record &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;record.path&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.&lt;font color="#008b8b"&gt;join&lt;/font&gt;(&lt;font color="#ff00ff"&gt;&amp;quot; &amp;quot;&lt;/font&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;svn commit -m &lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;${commitTextPane.text}&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&amp;nbsp;$fileList&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&amp;quot;.system()&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.exit(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;)&lt;br /&gt;} &lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;ActionListener)&lt;br /&gt;&lt;br /&gt;refreshButton.addActionListener({ event &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reloadChangedFiles()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;jtable.revalidate()&lt;br /&gt;} &lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;ActionListener)&lt;br /&gt;&lt;br /&gt;wnd.visible = &lt;font color="#ff00ff"&gt;true&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Notice that I'm heavily using closures as means to define actions in the GUI and have access to the context variables. Also the reason to pick MigLayout wasn't done at random. I think it's the best layout manager out there (you'll need it in ~/.groovy/lib).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I hope it helps.&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-2581611652232504128?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/2581611652232504128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=2581611652232504128' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2581611652232504128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2581611652232504128'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/03/groovy-scripting.html' title='Groovy scripting'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/ScoGn8jcvAI/AAAAAAAAAEg/VR5zMgzviU4/s72-c/Screenshot-commit-3.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-564864957874399341</id><published>2009-03-09T04:14:00.000-07:00</published><updated>2009-03-09T05:00:34.080-07:00</updated><title type='text'>Using DLR in your application from C#</title><content type='html'>What is DLR?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Dynamic_Language_Runtime"&gt;DLR&lt;/a&gt; is a high level framework used to create dynamic language compilers on top of .NET Framework. Some of the advantages of it is that any language it registers to that framework, thus changing the support to any DLR language, is mainly adding a reference that consists in the language implementation and one string to identify it. This post will focus on &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt;IronPython&lt;/a&gt; which is better documented, but in fact it should be the same as using &lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; that uses the same DLR engine (so GetEngine ("rb") should be used instead).&lt;br /&gt;&lt;br /&gt;What does a DLR language implementation consist in?&lt;br /&gt;Firstly, a ScriptEngine class is the implementation of the language itself (it is defined under the Microsoft.Scripting.Hosting). This ScriptEngine will offer you a DLR based engine that is offering all that you will need to do with the language.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's create one:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;ScriptEngine engine = Python.CreateEngine(); &lt;font color="#0000ff"&gt;// if you use the direct IronPython&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;// interface to do so or (more generic):&lt;/font&gt;&lt;br /&gt;engine = ScriptRuntime.Create().GetEngine(&lt;font color="#ff00ff"&gt;&amp;quot;py&amp;quot;&lt;/font&gt;);&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;From this engine you get an instance of the IronPython runtime. How can you add references? As the dynamic languages have multiple modules (that might depend from one language to another), there is a need to define such modules, and one of the predefined modules, that is defined to work with .NET types is named &lt;b&gt;clr&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;ScriptRuntime runtime = engine.Runtime;&lt;br /&gt;runtime.ImportModule(&lt;font color="#ff00ff"&gt;&amp;quot;clr&amp;quot;&lt;/font&gt;);&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Next, you will create a scope that executes in "the context" of your program. Think to scopes, as a new method call. All contexts share the same runtime! Thus if you want one scope to use CLR, but another one to be restricted, you should create two engines! Every scope has its own variables defined into it.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;ScriptScope scope = engine.CreateScope();&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;From now on, you can execute your code in ironPython when you create a Scope.&lt;br /&gt;&lt;br /&gt;The C# code to execute an arbitrary code is like the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ExecutePythonCode(&lt;font color="#2e8b57"&gt;&lt;b&gt;string&lt;/b&gt;&lt;/font&gt;&amp;nbsp;code)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ScriptSource source = engine.CreateScriptSourceFromString(code, SourceCodeKind.Statements);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;source.Execute(scope);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(Exception e)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(e.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Not powerful enough yet? If you have your own variables and you want to modify them from the scripting, all you have to write is:&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;scope.SetVariable(&lt;font color="#ff00ff"&gt;&amp;quot;pythonVarName&amp;quot;&lt;/font&gt;, yourCsVariable);&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And the new variable is mapped dynamically, so you can change the data in it as is a python class instance. So you may write in your script: pythonVarName.ToString() at any moment!&lt;br /&gt;&lt;br /&gt;One last note: how to import from IronPython System.Windows.Forms namespace, or any other instance: you have to do two things:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;adding a reference to necessary assembly,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;do the "using" C# part, means to import the namespace to your program&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;clr.AddReference(&amp;quot;&lt;font color="#ff00ff"&gt;System.Windows.Forms&lt;/font&gt;&amp;quot;)&lt;br /&gt;&lt;font color="#a020f0"&gt;from&lt;/font&gt;&amp;nbsp;System.Windows.Forms &lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;*&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-564864957874399341?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/564864957874399341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=564864957874399341' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/564864957874399341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/564864957874399341'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/03/using-dlr-in-your-application-from-c.html' title='Using DLR in your application from C#'/><author><name>ciplogic</name><uri>http://www.blogger.com/profile/05409605028353356569</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5820961668781081551</id><published>2009-03-02T03:57:00.000-08:00</published><updated>2009-03-08T13:00:19.575-07:00</updated><title type='text'>IE6, Select, Z-index and a Prototype solution</title><content type='html'>Aren't you pissed off about that IE6 (old since the beginning of the world) bug that ignores the z-index for all the combos in the page? Thus all the combos from the page creep on the top div, like mushrooms in an Amazonian forest.&lt;br /&gt;&lt;br /&gt;I know that people should just throw down the toilet that "magnificent" browser, but sometimes the company you work for, decides to support IE6, so you really don't have a choice.&lt;br /&gt;&lt;br /&gt;Anyway, here are some functions that use prototype, that workaround this issue by hiding/showing all the combos on the page if the version of the browser it's IE6.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color="#008b8b"&gt;function&lt;/font&gt;&amp;nbsp;showSelects()&amp;nbsp;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;2 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&lt;font color="#a52a2a"&gt;&lt;b&gt;document&lt;/b&gt;&lt;/font&gt;.body).select(&lt;font color="#ff00ff"&gt;&amp;quot;select&amp;quot;&lt;/font&gt;).each(&lt;font color="#008b8b"&gt;function&lt;/font&gt;(select)&amp;nbsp;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;3 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select.show();&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;4 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;}&lt;/font&gt;);&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;5 &lt;/font&gt;&lt;font color="#008b8b"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;&lt;font color="#008b8b"&gt;function&lt;/font&gt;&amp;nbsp;hideSelects()&amp;nbsp;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$(&lt;font color="#a52a2a"&gt;&lt;b&gt;document&lt;/b&gt;&lt;/font&gt;.body).select(&lt;font color="#ff00ff"&gt;&amp;quot;select&amp;quot;&lt;/font&gt;).each(&lt;font color="#008b8b"&gt;function&lt;/font&gt;(select)&amp;nbsp;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;select.hide();&lt;br /&gt;&lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;}&lt;/font&gt;);&lt;br /&gt;&lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&lt;font color="#008b8b"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;12 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;13 &lt;/font&gt;&lt;font color="#008b8b"&gt;function&lt;/font&gt;&amp;nbsp;isIE6()&amp;nbsp;&lt;font color="#008b8b"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;14 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Prototype.Browser.IE &amp;amp;&amp;amp; navigator.appVersion.indexOf(&lt;font color="#ff00ff"&gt;&amp;quot;MSIE 6.0&amp;quot;&lt;/font&gt;)&amp;nbsp;!= -1;&lt;br /&gt;&lt;font color="#a52a2a"&gt;15 &lt;/font&gt;&lt;font color="#008b8b"&gt;}&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That's pretty much it. I hope you'll find it useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5820961668781081551?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5820961668781081551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5820961668781081551' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5820961668781081551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5820961668781081551'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/03/ie6-select-z-index-and-prototype.html' title='IE6, Select, Z-index and a Prototype solution'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4343633658091854243</id><published>2009-02-20T04:51:00.000-08:00</published><updated>2009-03-08T13:00:28.633-07:00</updated><title type='text'>Dynamic Method Creation</title><content type='html'>I don't know about you guys, but I think programming it's hard. It's hard, because we have a lot of technical challenges, made of functional and non-functional constraints. We need to learn their whole business in order to be able to to craft their product as they wish.&lt;br /&gt;&lt;br /&gt;And this is hard.&lt;br /&gt;&lt;br /&gt;We are forced to learn so many things, that we can not base our knowledge on our brain, but want the tooling (IDEs) to do autocomplete for us. This is embarrassing at least. We create such complex systems that, most of the time, without tooling we can not feasible maintain them anymore.&lt;br /&gt;&lt;br /&gt;And there is where dynamic languages come to the rescue.&lt;br /&gt;&lt;br /&gt;What if the objects that we're modeling upon could deduce our intent in using them? They weren't be some dumb data structures, but could actually figure out from what we're asking them what we mean, and "compose" their behavior transparently to provide us what we want.&lt;br /&gt;&lt;br /&gt;Take a look at the following code (it's not very useful, but it's a good starting example):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;1 &lt;/font&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CoolObject {&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;2 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;invokeMethod(&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;&amp;nbsp;name, &lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;args)&amp;nbsp;{&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;3 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(name.startsWith(&lt;font color="#ff00ff"&gt;&amp;quot;say&amp;quot;&lt;/font&gt;))&amp;nbsp;{&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;4 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;words = []&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;5 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;currentWord = &lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;6 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;7 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name.substring(&lt;font color="#ff00ff"&gt;3&lt;/font&gt;).&lt;font color="#008b8b"&gt;each&lt;/font&gt;&amp;nbsp;{ letter &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;8 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(letter.equals(letter.toUpperCase()))&amp;nbsp;{&lt;br /&gt;&lt;font color="#a52a2a"&gt;&amp;nbsp;9 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;words.add currentWord&lt;br /&gt;&lt;font color="#a52a2a"&gt;10 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentWord = &lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;11 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;12 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentWord += letter&lt;br /&gt;&lt;font color="#a52a2a"&gt;13 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;14 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;words.add currentWord&lt;br /&gt;&lt;font color="#a52a2a"&gt;15 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;16 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;print&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&lt;/font&gt;&lt;font color="#008b8b"&gt;${args[0]}&lt;/font&gt;&lt;font color="#ff00ff"&gt;&amp;nbsp;you are&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;17 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;words.&lt;font color="#008b8b"&gt;collect&lt;/font&gt;&amp;nbsp;{&lt;br /&gt;&lt;font color="#a52a2a"&gt;18 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;it == &lt;font color="#ff00ff"&gt;&amp;quot;Dash&amp;quot;&lt;/font&gt;&amp;nbsp;? &lt;font color="#ff00ff"&gt;&amp;quot;-&amp;quot;&lt;/font&gt;&amp;nbsp;: it&lt;br /&gt;&lt;font color="#a52a2a"&gt;19 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.&lt;font color="#008b8b"&gt;each&lt;/font&gt;&amp;nbsp;{&lt;br /&gt;&lt;font color="#a52a2a"&gt;20 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;print&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;$it &amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;21 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;22 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;23 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;24 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;args[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;]&lt;br /&gt;&lt;font color="#a52a2a"&gt;25 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;26 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;27 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;super&lt;/b&gt;&lt;/font&gt;.invokeMethod(name, args)&lt;br /&gt;&lt;font color="#a52a2a"&gt;28 &lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;29 &lt;/font&gt;}&lt;br /&gt;&lt;font color="#a52a2a"&gt;30 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;31 &lt;/font&gt;CoolObject coolObject = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CoolObject()&lt;br /&gt;&lt;font color="#a52a2a"&gt;32 &lt;/font&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;33 &lt;/font&gt;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;coolObject.saySomeoneCool(&lt;font color="#ff00ff"&gt;&amp;quot;John&amp;quot;&lt;/font&gt;)&lt;br /&gt;&lt;font color="#a52a2a"&gt;34 &lt;/font&gt;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;coolObject.saySomeoneReallyDashReallyCool(&lt;font color="#ff00ff"&gt;&amp;quot;Mary&amp;quot;&lt;/font&gt;)&lt;br /&gt;&lt;font color="#a52a2a"&gt;35 &lt;/font&gt;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;coolObject.toString()&lt;br /&gt;&lt;font color="#a52a2a"&gt;36 &lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, "cool object" doesn't have any method named &lt;span style="font-weight:bold;"&gt;saySomeoneCool&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;saySomeoneReallyDashReallyCool&lt;/span&gt;. But it knows how to interpret them in case you call them. And I can still call the existing functions (toString).&lt;br /&gt;&lt;br /&gt;When running it with groovy the following output goes out:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;John you are Someone Cool&lt;br /&gt;John&lt;br /&gt;Mary you are Someone Really - Really Cool&lt;br /&gt;Mary&lt;br /&gt;CoolObject@1267649&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;To this point this is just another way of sending arguments (using the method name instead of creating a generic method "say" and giving there whatever needs to be told) - which is not mind blowing. The only cool thing, is that you can actually get a feeling on what it does from the naming only.&lt;br /&gt;&lt;br /&gt;But here are some places where it is really neat to have the capability of "creating" methods on the fly:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="font-weight:bold;"&gt;Finders&lt;/span&gt;:&lt;br /&gt; object.&lt;span style="font-weight:bold;"&gt;findWhereNameIsLikeAndSurnameEquals&lt;/span&gt;("Moo", "Foo")&lt;br /&gt; compared to&lt;br /&gt; object.&lt;span style="font-weight:bold;"&gt;findWhereSurnameEqualsAndNameIsLike&lt;/span&gt;("Foo", "Moo")&lt;br /&gt;&lt;br /&gt;They have the exact same meaning, and you can deduce it from the method names. (They are actually widely used already, in frameworks like "grails").&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Extended behaviour&lt;/span&gt;:&lt;br /&gt; object.&lt;span style="font-weight:bold;"&gt;runInTransactionMooFunction&lt;/span&gt;(mooArg1, mooArg2, ...)&lt;br /&gt;&lt;br /&gt;Let's assume that object has a &lt;span style="font-weight:bold;"&gt;mooFunction&lt;/span&gt;, &lt;span style="font-weight:bold;"&gt;runInTransaction&lt;/span&gt; could ensure starting and committing a transaction, or rolling back if something bad happened, etc.&lt;br /&gt;&lt;br /&gt;(actually "Finders" and "Extended behaviour" are belonging in the same AND kind of functionality -&lt;br /&gt;run this AND that -, without duplicating code, or creating bogus functions that just link them; I could translate the &lt;span style="font-weight:bold;"&gt;runInTransactionMooFunction&lt;/span&gt; as &lt;span style="font-weight:bold;"&gt;startTransactionAndMooFunction&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;I could still call object.&lt;span style="font-weight:bold;"&gt;mooFunction&lt;/span&gt;(mooArg1, mooArg2, ...) if I've managed my own transaction.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;"Correcting" behaviour&lt;/span&gt;:&lt;br /&gt; object.&lt;span style="font-weight:bold;"&gt;toZtring&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;Could actually search for the nearest named method, call it (because it's obviously my intent),&lt;br /&gt;and print a warning that I'm using the wrongly named function.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Transparent proxying/decorating&lt;/span&gt;:&lt;br /&gt; It's really-really trivial to create now proxying of any kind, and change the behavior of some methods without using inheritance.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This doesn't want to be by any means a complete list of what you can do if you are able to aggregate behavior just by analyzing the message passed to you.&lt;br /&gt;&lt;br /&gt;But it is meant to show you the immense capabilities between the "simple" analyzing of the method name called, and interpreting that for behavior, instead of just creating endless methods.&lt;br /&gt;&lt;br /&gt;As an end note, I don't think that using this kind of approach would totally remove the need for tooling. But I am certain, beyond any reasonable doubt, that it will reduce our dependency on it.&lt;br /&gt;&lt;br /&gt;And our code will express more our intent.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4343633658091854243?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4343633658091854243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4343633658091854243' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4343633658091854243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4343633658091854243'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/02/dynamic-method-creation.html' title='Dynamic Method Creation'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7159514538579237960</id><published>2009-02-17T07:41:00.000-08:00</published><updated>2009-02-17T07:59:35.430-08:00</updated><title type='text'>JavaFX training</title><content type='html'>Who hasn't heard of it? Who doesn't want to know about it? For all of you java web developers out there, this should be an interesting course. And it's free for SDN members!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.sun.com/offers/images/JavaFX_training.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 255px; height: 200px;" src="http://www.sun.com/offers/images/JavaFX_training.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;(If after the Solaris playground you're not yet an SDN member, I am wondering what's wrong with you people anyway :).)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sun.com/offers/details/JavaFX_training.html"&gt;This is a training course&lt;/a&gt; I really want to take.&lt;br /&gt;&lt;br /&gt;I'll come back in around a month with updates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7159514538579237960?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7159514538579237960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7159514538579237960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7159514538579237960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7159514538579237960'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/02/javafx-training.html' title='JavaFX training'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7919882414161576678</id><published>2009-02-05T13:34:00.000-08:00</published><updated>2009-02-05T13:43:39.707-08:00</updated><title type='text'>Play with OpenSolaris on a remote virtual machine</title><content type='html'>Sun has made available (for registered members of Sun Developers Network) one hour of free play on one of their virtual machines loaded with Solaris.&lt;br /&gt;&lt;br /&gt;Link: &lt;a href="https://learning.sun.com/solc/course/sandbox-1"&gt;https://learning.sun.com/solc/course/sandbox-1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can play chess:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/SYtcexQHFTI/AAAAAAAAADw/ESU8R3cvsI8/s1600-h/Screenshot-6.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 125px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/SYtcexQHFTI/AAAAAAAAADw/ESU8R3cvsI8/s200/Screenshot-6.png" alt="" id="BLOGGER_PHOTO_ID_5299431070218261810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;... you can see the package manger in action (and remove or add programs, since you have root access):&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/SYtcfMOBRkI/AAAAAAAAAD4/DP-Opdqvr64/s1600-h/Screenshot-7.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 125px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/SYtcfMOBRkI/AAAAAAAAAD4/DP-Opdqvr64/s200/Screenshot-7.png" alt="" id="BLOGGER_PHOTO_ID_5299431077457249858" border="0" /&gt;&lt;/a&gt;... and, yes, &lt;a href="http://opensolaris.org/os/community/zfs/"&gt;(the ahead of its time) zfs&lt;/a&gt; it's also there:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/SYtcf3YzByI/AAAAAAAAAEA/gJH8u4j4utg/s1600-h/Screenshot-8.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 125px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/SYtcf3YzByI/AAAAAAAAAEA/gJH8u4j4utg/s200/Screenshot-8.png" alt="" id="BLOGGER_PHOTO_ID_5299431089045178146" border="0" /&gt;&lt;/a&gt;How cool is that?&lt;br /&gt;&lt;br /&gt;I just wait to test it in VirtualBox.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7919882414161576678?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7919882414161576678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7919882414161576678' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7919882414161576678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7919882414161576678'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/02/play-with-opensolaris-on-remote-virtual.html' title='Play with OpenSolaris on a remote virtual machine'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/SYtcexQHFTI/AAAAAAAAADw/ESU8R3cvsI8/s72-c/Screenshot-6.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6686784402137430257</id><published>2009-02-05T08:57:00.000-08:00</published><updated>2009-02-05T09:00:32.621-08:00</updated><title type='text'>SCJP - Sun Certified Java Programmer - You think you're good?</title><content type='html'>So you think you know Java?&lt;br /&gt;&lt;br /&gt;Sun made free a simulation of their SCJP test. All the questions are from plain java.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.sun.com/training/certification/assessment/055-Jintro.jsp"&gt;http://www.sun.com/training/certification/assessment/055-Jintro.jsp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Come on, go ahead and try it... it's free anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6686784402137430257?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6686784402137430257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6686784402137430257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6686784402137430257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6686784402137430257'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/02/scjp-sun-certified-java-programmer-you.html' title='SCJP - Sun Certified Java Programmer - You think you&apos;re good?'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7301675595357807938</id><published>2009-01-16T16:15:00.000-08:00</published><updated>2009-02-07T10:42:55.628-08:00</updated><title type='text'>Writing Better Code - A Step By Step Analysis</title><content type='html'>I was asked recently to evaluate the following function:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SortUtils {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;K, V&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sortMapByValueSize(Map&amp;lt;K, Collection&amp;lt;V&amp;gt;&amp;gt; mapArg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(!(mapArg &lt;font color="#a52a2a"&gt;&lt;b&gt;instanceof&lt;/b&gt;&lt;/font&gt;&amp;nbsp;LinkedHashMap))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;throw&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;IllegalArgumentException(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;gt;&amp;gt;&amp;gt; The argument has to be a LinkedHashMap in order for the swapping to be saved.&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;K&amp;gt; keys = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ArrayList&amp;lt;K&amp;gt;(mapArg.keySet());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;Collection&amp;lt;V&amp;gt;&amp;gt; values = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ArrayList&amp;lt;Collection&amp;lt;V&amp;gt;&amp;gt;(mapArg&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.values());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;Collection&amp;lt;V&amp;gt;&amp;gt; copyOfValues = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;ArrayList&amp;lt;Collection&amp;lt;V&amp;gt;&amp;gt;(values);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;genericSortBySize(copyOfValues);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapArg.clear();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; copyOfValues.size(); ++i)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapArg.put(keys.get(values.indexOf(copyOfValues.get(i))),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;copyOfValues.get(i));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;T&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;genericSortBySize(List&amp;lt;Collection&amp;lt;T&amp;gt;&amp;gt; x)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;n = x.size();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;pass = &lt;font color="#ff00ff"&gt;1&lt;/font&gt;; pass &amp;lt; n; ++pass)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(ListIterator&amp;lt;Collection&amp;lt;T&amp;gt;&amp;gt; li = x.listIterator(&lt;font color="#ff00ff"&gt;0&lt;/font&gt;); li.hasNext()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;&amp;amp; (i &amp;lt; n - pass);)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Collection&amp;lt;T&amp;gt; tmp = li.next();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i = x.indexOf(tmp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(tmp.size()&amp;nbsp;&amp;gt; x.get(i + &lt;font color="#ff00ff"&gt;1&lt;/font&gt;).size())&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Collection&amp;lt;T&amp;gt; temp = tmp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.set(x.get(i + &lt;font color="#ff00ff"&gt;1&lt;/font&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.next();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.set(temp);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;li.previous();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;++i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This code is supposed to receive a LinkedHashMap with some generic keys, and as value a collection of stuff. It should sort the items by the number of the elements in the collections.&lt;br /&gt;&lt;br /&gt;When I see this kind of code, I always have a mini seizure. First of all, because I can't figure out from the first look what is that code really doing. Second of all &lt;a href="http://en.wikipedia.org/wiki/Code_smell"&gt;I can smell&lt;/a&gt; problems. (Yes, code does smell).&lt;br /&gt;&lt;br /&gt;This one has a peculiar stink, and unless you're not completely blind, at least the function &lt;strong&gt;genericSortBySize&lt;/strong&gt; should raise you some questions. For starters: what does it do?&lt;br /&gt;&lt;br /&gt;At a first sight it's a &lt;a href="http://en.wikipedia.org/wiki/Na%C3%AFve_algorithm"&gt;naive&lt;/a&gt; sorting done via bubble sort. Thus the complexity is at least &lt;a href="http://en.wikipedia.org/wiki/Big_o_notation"&gt;O(n&lt;sup&gt;2&lt;/sup&gt;)&lt;/a&gt;. That's a bad sign.&lt;br /&gt;&lt;br /&gt;There are others: the variables are written in an &lt;a href="http://en.wikipedia.org/wiki/Encrypted"&gt;encrypted&lt;/a&gt; style. You need to be the actual programmer who wrote them to really figure out what's happening there.&lt;br /&gt;&lt;br /&gt;Are you watching closely? (to quote a &lt;a href="http://www.imdb.com/title/tt0482571/"&gt;certain magician&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;I've mislead you a bit. What's the complexity of the algorithm come again? You think it's O(n&lt;sup&gt;2&lt;/sup&gt;)? If yes, then you're wrong. I've said "at least". This one has a neat "feature" of having the complexity... drums beating.. O(n&lt;sup&gt;3&lt;/sup&gt;). In case you didn't see it, look again in the code: Yup, it's that indexOf.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i = x.indexOf(tmp);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;It is clearly that the original author didn't knew about the existence of Collections.* algorithm functions. One of them is called &lt;b&gt;sort&lt;/b&gt; and guarantees O(n * log(n)) complexity.&lt;br /&gt;&lt;br /&gt;Thus we could refactor that method like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;T&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;genericSortBySize(List&amp;lt;Collection&amp;lt;T&amp;gt;&amp;gt; collectionsList)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Collections.sort(collectionsList, &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Comparator&amp;lt;Collection&amp;lt;T&amp;gt;&amp;gt;()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;compare(Collection&amp;lt;T&amp;gt; o1, Collection&amp;lt;T&amp;gt; o2)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;o1.size()&amp;nbsp;- o2.size();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now, not only the complexity went from O(n&lt;sup&gt;3&lt;/sup&gt;) to O(n * log(n)) but also we can read the code, and we fixed a bug present in the code. If you didn't see it, don't worry, it's easy to miss it in that mess. I'm not going to pinpoint the bug, but believe me, it is there, and I'll leave it as an exercise for the careful reader.&lt;br /&gt;&lt;br /&gt;Another problem arises, now that our code is more clearer. It's located here:&lt;br /&gt;&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;i = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;; i &amp;lt; copyOfValues.size(); ++i)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapArg.put(keys.get(values.indexOf(copyOfValues.get(i))),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;copyOfValues.get(i));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The way the algorithm was designed is in such a way, that even if we fixed that, we still have O(n&lt;sup&gt;2&lt;/sup&gt; * m) complexity. Yup, that's an M since the searching for the key is using again... indexOf. The problem with this brilliant construct is how it's implemented. It will actually iterate over the each element of the list &lt;b&gt;and&lt;/b&gt; call equals on each element, with the argument it received.&lt;br /&gt;&lt;br /&gt;The problem is, you've guessed, that our elements are... erm... Lists. Thus, equals will go into them as well, and call equals on each argument. For our benchmarks, we've used numbers. In real life it could have been much more costly in terms of processing power. Assuming all the lists have an equal number of elements (let's say m), the complexity is now O(n&lt;sup&gt;2&lt;/sup&gt; * m). (If you've watched closely as instructed, you would know that the previous function had it as O(n&lt;sup&gt;3&lt;/sup&gt; * m)).&lt;br /&gt;&lt;br /&gt;Thus the only viable option remain the full rewriting of the  code. The original author of the code didn't knew probably of the existence of TreeMap. TreeMap has this very nice property that the insert/remove on it have the "cost" of O(log(n)), &lt;b&gt;but&lt;/b&gt; it keeps the items sorted inside.&lt;br /&gt;&lt;br /&gt;Thus, all we really need to do is add the items in a TreeMap [n items * log(n) per item, should be a cozy O(n * log(n))]. Then all we need to do is to iterate on the sorted keyset and just put the values in the other map. (again, under O(n * log(n)) ).&lt;br /&gt;&lt;br /&gt;Thus the code now looks like (we even kept the same API for our external users):&lt;br /&gt;&lt;div style="border:black solid 1px; font-family : monospace; font-size : 10px"&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CollectionHolder &lt;font color="#2e8b57"&gt;&lt;b&gt;implements&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Comparable&amp;lt;CollectionHolder&amp;gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Collection collection;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;index;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;lastIndex;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CollectionHolder(Collection collection)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;.collection = collection;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;.index = CollectionHolder.lastIndex++;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;compareTo(CollectionHolder other)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;cmp = &lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;.collection.size()&amp;nbsp;- other.collection.size();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(cmp == &lt;font color="#ff00ff"&gt;0&lt;/font&gt;)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;.index - other.index;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;font color="#a52a2a"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;cmp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;boolean&lt;/b&gt;&lt;/font&gt;&amp;nbsp;equals(Object obj)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/font&gt;&amp;nbsp;== obj;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;SortUtils2 {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;Key, Value&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sortMapByValueSize(Map&amp;lt;Key, Collection&amp;lt;Value&amp;gt;&amp;gt; mapArg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;validateArgumentMap(mapArg);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;CollectionHolder, Key&amp;gt; valuesMap = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;TreeMap&amp;lt;CollectionHolder, Key&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sortArgumentMapIntoValuesMap(mapArg, valuesMap);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clearArgumentMap(mapArg);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;putValuesMapIntoArgumentMap(mapArg, valuesMap);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;Key, Value&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;validateArgumentMap(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;Key, Collection&amp;lt;Value&amp;gt;&amp;gt; mapArg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(!(mapArg &lt;font color="#a52a2a"&gt;&lt;b&gt;instanceof&lt;/b&gt;&lt;/font&gt;&amp;nbsp;LinkedHashMap))&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;throw&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;IllegalArgumentException(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#ff00ff"&gt;&amp;quot;&amp;gt;&amp;gt;&amp;gt; The argument has to be a LinkedHashMap in order for the swapping to be saved.&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;Key, Value&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;sortArgumentMapIntoValuesMap(Map&amp;lt;Key, Collection&amp;lt;Value&amp;gt;&amp;gt; mapArg,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;CollectionHolder, Key&amp;gt; valuesMap)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(Key key : mapArg.keySet())&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;valuesMap.put(&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CollectionHolder(mapArg.get(key)), key);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;Key, Value&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;clearArgumentMap(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;Key, Collection&amp;lt;Value&amp;gt;&amp;gt; mapArg)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapArg.clear();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;private&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&amp;lt;Key, Value&amp;gt; &lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;putValuesMapIntoArgumentMap(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;Key, Collection&amp;lt;Value&amp;gt;&amp;gt; mapArg, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Map&amp;lt;CollectionHolder, Key&amp;gt; valuesMap)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(CollectionHolder holder : valuesMap.keySet())&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapArg.put(valuesMap.get(holder), holder.collection);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You might say that maybe we didn't save that much... For those of you still living in denial, here are some benchmarks. I've run the initial code over the same kind of arrays. They were having either 1, 11, 21, or 31 elements, and &lt;b&gt;the elements &lt;/b&gt;&lt;b&gt;were having the same value&lt;/b&gt; (they were an Integer, with the value 10), and more and more collections we're added (up to ~600).&lt;br /&gt;&lt;br /&gt;It's very important since whenever you see indexOf() the complexity it's not O(n), but O(1). A lot of comparisons are now gone away. It is still O(n&lt;sup&gt;2&lt;/sup&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ie5BPcoUm-I/SXEzVQ1dEjI/AAAAAAAAADY/_kNRg4nOHZg/s1600-h/sort_util_orig.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 120px;" src="http://2.bp.blogspot.com/_ie5BPcoUm-I/SXEzVQ1dEjI/AAAAAAAAADY/_kNRg4nOHZg/s400/sort_util_orig.png" alt="" id="BLOGGER_PHOTO_ID_5292067477526483506" border="0" /&gt;&lt;/a&gt;The next thing I've did, was just to have distinct numbers in the arrays. The times skyrocketed:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/SXEz3TLyv-I/AAAAAAAAADg/jyK3NkHHmTY/s1600-h/sort_util_orig_diff.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 115px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/SXEz3TLyv-I/AAAAAAAAADg/jyK3NkHHmTY/s400/sort_util_orig_diff.png" alt="" id="BLOGGER_PHOTO_ID_5292068062272602082" border="0" /&gt;&lt;/a&gt;We went from milliseconds to seconds in a blink. An the last implementation, the one with the TreeMap follows:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ie5BPcoUm-I/SXE0PClLjYI/AAAAAAAAADo/zJV40dd5VCg/s1600-h/sort_refactored.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 117px;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/SXE0PClLjYI/AAAAAAAAADo/zJV40dd5VCg/s400/sort_refactored.png" alt="" id="BLOGGER_PHOTO_ID_5292068470132542850" border="0" /&gt;&lt;/a&gt;Except a single one (most likely caused by scheduling), all of the times where less or equal 4 milliseconds.&lt;br /&gt;&lt;br /&gt;Conclusions:&lt;br /&gt;1. The wordpress team says "Code is poetry". Make your code at least human readable. The bugs should stand right at you if any. (if not, see pt. 4)&lt;br /&gt;2. Understand your underlying API and find the algorithms implemented by your platform. (even C and C++ have them - hint for C++: STL and boost, search and get aquinted with them,  before writing naive code).&lt;br /&gt;3. Understand what the basic functions do on the collection classes. You might not want to popFirst from a queue if it's implemented with a list.&lt;br /&gt;4. Refactor your code to get better insight, and don't let you're code rot.&lt;br /&gt;5. Write tests. They are the only (slim as it is) guarantee that your code does what you think it does. The bug found in this code was found by a test. I didn't just "see" it.&lt;br /&gt;6. Performance does matter, but it's driven from the algorithm, not from "clever hacks that work". You can never prove the performance of a hack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7301675595357807938?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7301675595357807938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7301675595357807938' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7301675595357807938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7301675595357807938'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2009/01/writing-better-code-step-by-step.html' title='Writing Better Code - A Step By Step Analysis'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ie5BPcoUm-I/SXEzVQ1dEjI/AAAAAAAAADY/_kNRg4nOHZg/s72-c/sort_util_orig.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6438344590634533850</id><published>2008-12-08T12:30:00.000-08:00</published><updated>2008-12-08T12:38:50.364-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dilbert'/><category scheme='http://www.blogger.com/atom/ns#' term='vista'/><category scheme='http://www.blogger.com/atom/ns#' term='mojave'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Just Dilbert</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ie5BPcoUm-I/ST2F1g2q_BI/AAAAAAAAACo/9JY97428xhs/s1600-h/dilbert.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 133px;" src="http://4.bp.blogspot.com/_ie5BPcoUm-I/ST2F1g2q_BI/AAAAAAAAACo/9JY97428xhs/s400/dilbert.png" alt="" id="BLOGGER_PHOTO_ID_5277521492746894354" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6438344590634533850?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6438344590634533850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6438344590634533850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6438344590634533850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6438344590634533850'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/12/just-dilbert.html' title='Just Dilbert'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ie5BPcoUm-I/ST2F1g2q_BI/AAAAAAAAACo/9JY97428xhs/s72-c/dilbert.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8357661273551033326</id><published>2008-12-03T04:51:00.000-08:00</published><updated>2009-03-08T12:57:07.635-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='short program'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>A short program to count lines of code</title><content type='html'>I've just seen &lt;a href="http://blogs.msdn.com/kirillosenkov/archive/2008/11/30/a-one-line-program-to-count-lines-of-code.aspx"&gt;this small C# program&lt;/a&gt; and I wondered how would it be done in groovy. My solution looks like this:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;#!/usr/bin/env groovy&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;funcName = (args.length &amp;gt; &lt;font color="#ff00ff"&gt;0&lt;/font&gt;&amp;nbsp;&amp;amp;&amp;amp; args[&lt;font color="#ff00ff"&gt;0&lt;/font&gt;]&amp;nbsp;== &lt;font color="#ff00ff"&gt;&amp;quot;/s&amp;quot;&lt;/font&gt;)&amp;nbsp;? &lt;font color="#ff00ff"&gt;&amp;quot;eachFileRecurse&amp;quot;&lt;/font&gt;&amp;nbsp;: &lt;font color="#ff00ff"&gt;&amp;quot;eachFile&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;font color="#6a5acd"&gt;def&lt;/font&gt;&amp;nbsp;lineCount = &lt;font color="#ff00ff"&gt;0&lt;/font&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;File(&lt;font color="#ff00ff"&gt;&amp;quot;.&amp;quot;&lt;/font&gt;).&lt;font color="#ff00ff"&gt;&amp;quot;$funcName&amp;quot;&lt;/font&gt;&amp;nbsp;{ f &lt;font color="#a52a2a"&gt;&lt;b&gt;-&amp;gt;&lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/font&gt;&amp;nbsp;(f.isFile())&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f.&lt;font color="#008b8b"&gt;eachLine&lt;/font&gt;&amp;nbsp;{ lineCount ++ }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;font color="#008b8b"&gt;println&lt;/font&gt;&amp;nbsp;lineCount&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;It is not a "one liner" (tm), but I don't believe in that.&lt;br /&gt;&lt;br /&gt;And some bash sayings:&lt;span style=";font-family:monospace;font-size:85%;"  &gt;&lt;br /&gt;&lt;br /&gt;raptor@raptor-laptop:~/foo$ cat countLines.cs  | tr -s " " " " | wc&lt;br /&gt;    17      31     343&lt;br /&gt;raptor@raptor-laptop:~/foo$ cat countLines.groovy  | tr -s " " " " | wc&lt;br /&gt;    13      37     235&lt;br /&gt;raptor@raptor-laptop:~/foo$&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(tr is used to minimize the impact of indentation in the counting)&lt;br /&gt;&lt;br /&gt;If someone has a solution in Python (or any other language for that matter), I would be really anxious to see it.&lt;br /&gt;&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8357661273551033326?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8357661273551033326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8357661273551033326' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8357661273551033326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8357661273551033326'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/12/short-program-to-count-lines-of-code.html' title='A short program to count lines of code'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-820657315147144404</id><published>2008-11-29T11:03:00.000-08:00</published><updated>2009-03-08T13:02:08.996-07:00</updated><title type='text'>Groovy and bash bring their love to the next level</title><content type='html'>You're hearing a lot these days about polyglot programing, or even&lt;br /&gt;creating console scripts with groovy.&lt;br /&gt;&lt;br /&gt;While I don't deny the power of using pure groovy shell scripts, I do believe that for a lot of tasks there is a true power in the shell. And it really doesn't make any sense to try to change that.&lt;br /&gt;&lt;br /&gt;But as you already may know, groovy can expand types, by adding methods at runtime. What we will do, is add a new &lt;span style="font-weight: bold;"&gt;system&lt;/span&gt; method to the String class.&lt;br /&gt;&lt;br /&gt;Now you can have code like the following:&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;// version changed as per Ted's comment - thank you Ted!&lt;/font&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;.metaClass.system = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;Runtime().exec([&lt;font color="#ff00ff"&gt;&amp;quot;/bin/bash&amp;quot;&lt;/font&gt;, &lt;font color="#ff00ff"&gt;&amp;quot;-c&amp;quot;&lt;/font&gt;, delegate]&amp;nbsp;&lt;font color="#6a5acd"&gt;as&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/font&gt;[]).&lt;font color="#6a5acd"&gt;in&lt;/font&gt;.text&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;span style="color: rgb(106, 90, 205);"&gt;def&lt;/span&gt; localVar = &lt;span style="color: rgb(255, 0, 255);"&gt;"GROOVY"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 139, 139);"&gt;println&lt;/span&gt; &lt;span style="color: rgb(255, 0, 255);"&gt;"""&lt;/span&gt;&lt;br /&gt; echo &lt;span style="color: rgb(255, 0, 255);"&gt;"localVar is $localVar and SHELL is &lt;/span&gt;&lt;span style="background-color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;\$&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;SHELL"&lt;/span&gt;&lt;br /&gt; localVar=&lt;span style="color: rgb(255, 0, 255);"&gt;"SHELL"&lt;/span&gt;&lt;br /&gt; echo &lt;span style="color: rgb(255, 0, 255);"&gt;"--------------------------------------"&lt;/span&gt;&lt;br /&gt; echo &lt;span style="color: rgb(255, 0, 255);"&gt;"localVar from groovy is $localVar and"&lt;/span&gt;&lt;br /&gt; echo &lt;span style="color: rgb(255, 0, 255);"&gt;"localVar from shell  is &lt;/span&gt;&lt;span style="background-color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;\$&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;localVar"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;""".system()&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;On the contrary, if no variables from groovy would be used, we can then use the triple ''' instead of """&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;'''&lt;/span&gt;&lt;br /&gt;bashvar=&lt;span style="color: rgb(255, 0, 255);"&gt;"foo test"&lt;/span&gt;&lt;br /&gt;echo $bashvar   &lt;span style="color: rgb(0, 0, 255);"&gt;# regular bash, no escaping of the variable is needed&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;'''.system().split("&lt;/span&gt;&lt;span style="color: rgb(106, 90, 205);"&gt;\n&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;").each { line -&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 139, 139);"&gt;println&lt;/span&gt; line&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;As you can see the second aproach is great if you want pure bash calls.&lt;br /&gt;&lt;br /&gt;Of course, the command launched doesn't need to be necessarily bash (it could be also, perl or python, or whatever scripting language you want as long as you can give it as a parameter the script to evaluate).&lt;br /&gt;&lt;br /&gt;But now it's easy to have the best of the both worlds: Java and bash.&lt;br /&gt;&lt;script language="javascript" src="http://ciplogic.com/js/dzone.js"&gt; &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-820657315147144404?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/820657315147144404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=820657315147144404' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/820657315147144404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/820657315147144404'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/11/groovy-and-bash-bring-their-love-to.html' title='Groovy and bash bring their love to the next level'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-2664555112476150077</id><published>2008-11-17T02:13:00.000-08:00</published><updated>2008-11-17T03:02:54.679-08:00</updated><title type='text'>My objects are returning!</title><content type='html'>Warning: this, by my standards, is a really long article.&lt;br /&gt;&lt;br /&gt;Being warned, have you ever wondered, why some people really love Object Oriented Programming?&lt;br /&gt;I am one of them, that believes that almost anything should be an object.&lt;br /&gt;&lt;br /&gt;But what are objects? I have read that objects are data and code. Is this simplistic approach true? Is this all that it is with objects?&lt;br /&gt;&lt;br /&gt;I've read once a comment that objects are no such a big deal since there were ADTs (Abstract Data Types) existing even before objects.&lt;br /&gt;&lt;br /&gt;Well, let us just dive in a bit and see what objects really are. Lets go first to the real world.&lt;br /&gt;&lt;br /&gt;Objects can be viewed really simplistic: Car, or tree, or house - sound familiar? Identifying an object by name, but without a specific reference is actually a Class in the programming world. You don't know what specific object is, but you know its type.&lt;br /&gt;&lt;br /&gt;But most likely if you are a car designer my simple wording might not suffice. When you hear "car" you immediately think in wheel, doors and tire terms. You decompose the original object into its components. While this has nothing to do with its original value, this clearly shows that objects are hierarchical.&lt;br /&gt;&lt;br /&gt;Furthermore we can see that objects are composed, and they have a structure. Nothing is really random. Everything has its place.&lt;br /&gt;&lt;br /&gt;But because we have a structure between objects, we can now navigate between objects, only by using wording descriptions, and we can identify other objects by meaning, or position. Identifying by name it's not mandatory anymore.&lt;br /&gt;&lt;br /&gt;"At the middle of the door we have a &lt;span style="font-style: italic;"&gt;thingie&lt;/span&gt; that normal people grab and twist in order to open the door". In your mind now it is clear that I am talking about a handle.&lt;br /&gt;&lt;br /&gt;In groovy this would look like:&lt;br /&gt;&lt;div size="2" style="border: 1px solid rgb(51, 51, 51); padding: 4px; font-family: courier; font-size: 85%;"&gt;println door.open // door.isOpen() should return false&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;def&lt;/span&gt; me = &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; Human()&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;def&lt;/span&gt; handle = door.middle.content&lt;br /&gt;me.grab( handle ) // setting a connection between a person and the handle&lt;br /&gt;handle.turn() // the handle is either turned by me, either turns automatically&lt;br /&gt;println door.open()&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Of course, if the door would be locked, handle.turn() would most likely have thrown a DoorIsLocked exception and call alarm.ring().&lt;br /&gt;&lt;br /&gt;The cool thing to remember is that I've used the handle only by referencing it via the door. I could have use it without knowing it is named a handle. Nor I need to know that the handle used wrong, triggers the alarm.&lt;br /&gt;&lt;br /&gt;Thus naming bundles together an object with description data, behavior and it gives it meaning.&lt;br /&gt;&lt;br /&gt;Short recap on what do we know about objects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;they can be viewed as simple or complex&lt;/li&gt;&lt;li&gt;in order to reference an object we either use direct naming "cat", or referencing it via its relations to other objects "cats end" (tail)&lt;/li&gt;&lt;li&gt;they have behaviour (cat meows, door opens, handle turns, etc.)&lt;/li&gt;&lt;li&gt;they have state (alarm rings if the door is locked, or door opens)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Because we are in the software world, there is only one thing we should add about "our" objects, compared to the real world.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;they represent concepts&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;They abstract a real object - for example a boat object would be just a reference, to a real boat, floating somewhere. Because they are only concepts, you could change them to reflect your view of the world. Nothing is carved in stone.&lt;br /&gt;&lt;br /&gt;Now here is the interesting part: programming using objects is very-very easy. You just model each object from the real world to a concept in the software, and continuously refine it ("refactor" for you, the fancy ones out there). The seems pretty easy. The problem is that the number of objects is quite big compared to the memory and speed of our computer.&lt;br /&gt;&lt;br /&gt;Thus, tricks must be involved to make this objects "live" somewhere, even if all of them couldn't be loaded all at once in memory. Here SQL comes into play. Via SQL we can represent our objects as "data", to persist them in the database, and when needed to load them from database. Some guys thought that using this, we could expand our objects lifetime.&lt;br /&gt;&lt;br /&gt;Another idea was to have some objects on one machine, and some other objects on other machines. Thus, we could share these objects, and then by calling some kind of service, obtain a reference to the object, and then manipulate it remotely. (CORBA, RMI, and co., could easily fit in).&lt;br /&gt;Other guys (cough, J2EE, cough) unfortunately thought: why bring references to the object? network is slow, etc. etc., so we'll just bring a Value Object over the wire. Which is basically only the data of an object, without its behaviur. (By analogy it would be a pig without life, good for hot dogs, pork chops or whatever, but it can still do nothing).&lt;br /&gt;So you want to use the pig in a service? Well, just send it back, and we'll resuscitate it via some DAO method. (As a side note, if you're using Spring and Hibernate a ping-pong with the pig back and forth to the service, and &lt;a href="http://forum.springframework.org/showthread.php?t=18951"&gt;you're out of luck&lt;/a&gt;. Most likely there is nothing more you can do for your pig.).&lt;br /&gt;&lt;br /&gt;Another problem, was that there are objects that cross classes boundaries. (A &lt;a href="http://en.wikipedia.org/wiki/Flying_boat"&gt;flying boat&lt;/a&gt;, is it a Boat?, is it a Plane?, or is it Superman? :) ). These kind of things, some may argue, are complex to model as objects. Also some items couldn't be, at that time, mapped easily on objects. What about transactions? Should they be objects?&lt;br /&gt;&lt;br /&gt;And what about stateless requests? Like HTTP. How about all this Web 1.0, Web 2.0 thing? How do you get objects when you have nothing to get them from?&lt;br /&gt;&lt;br /&gt;This changed the easy OOP programming. Instead, it became a kind of &lt;a href="http://www.imdb.com/title/tt0126029/"&gt;Shrek&lt;/a&gt;, an ogre outside, but a warm hearted friend for conaisseurs. It also gave bread for writers of GOF, POSA1, POSA2 and other pattern books. It made things like dependency injection, aspect programming or object relational mapping sound like alien crafted words, where only wizards like Gandalf the Gray, or Saruman could go in their depth.&lt;br /&gt;&lt;br /&gt;Languages like C++, Java or C# only accentuated this problem. Their biggest issue is, in my humble opinion, that they either forced the user to classify objects extremely well, either add unnatural complexities (like the long life of Gollum - C++ shines on this one, my precious...). And since we were talking about Superman, if I would have such a construct:&lt;br /&gt;&lt;div   style="border: 1px solid rgb(51, 51, 51); padding: 4px;font-family:courier;font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;def&lt;/span&gt; superman = callSuperman()&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;assert&lt;/span&gt; !(superman &lt;span style="font-weight: bold;"&gt;instanceof&lt;/span&gt; Bird)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;assert&lt;/span&gt; !(superman &lt;span style="font-weight: bold;"&gt;instanceof&lt;/span&gt; Plane)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;assert&lt;/span&gt; (superman &lt;span style="font-weight: bold;"&gt;instanceof&lt;/span&gt; Superman)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I can allmost bet you, that if I would have to implement Superman in Java (C#, etc.), since Superman does have the abilities (behaviour) of a Bird or a Plane, Superman would either be a Bird and a Plane at the same time - beat that, you existentialists -, either it would secretly have a bird and a plane in its internals and secretly using them for flying (in some books this would be called composition, but don't rely on that). There is no way I could reuse only parts of an object in a clean way - at least, not that I know of (in Java that is).&lt;br /&gt;&lt;br /&gt;So, we've seen what objects are, and we've seen some problems that actually only the software world introduced them.&lt;br /&gt;&lt;br /&gt;Now here is where ORM comes into play. (ORM == Object Relational Mapping) ORM can fix one of our main issues - not having all the data. You do remember that I was unhappy because of SQL. Let me expand on why I am unhappy about it.&lt;br /&gt;&lt;br /&gt;I like to think that my objects are... erm... objects. Simple as that. But since I can not hold them all in memory I, until quite recently, need tricks like the following (remember the door example):&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid rgb(51, 51, 51); padding: 4px; font-family: courier; font-size: 85%;"&gt;println door.open // door.isOpen() should return false&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;def&lt;/span&gt; me = &lt;span style="font-weight: bold;"&gt;new&lt;/span&gt; Human()&lt;br /&gt;door.middle = DoorSQLService.loadMiddle(door); // whatever way you are loading doors&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;def&lt;/span&gt; handle = door.middle.content&lt;br /&gt;me.grab( handle ) // setting a connection between a person and the handle&lt;br /&gt;// the alarm it is possible not to be linked to the handle, so we'll add it now:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;if&lt;/span&gt; (handle.alarm == &lt;span style="font-weight: bold;"&gt;null&lt;/span&gt;) {&lt;br /&gt; handle.alarm = AlarmSQLService.loadAlarm(handle);&lt;br /&gt;}&lt;br /&gt;handle.turn() // the handle is either turned by me, either turns automatically&lt;br /&gt;println door.open()&lt;/div&gt;&lt;br /&gt;Now this totally messes up with our concept of objects. Objects aren't simple anymore. We need services to access them. Also, maybe this services need to be set up to some SQL databases, the loadMiddle and loadAlarm, should be implemented. Are they having any object behavior? They just seem to load data, without any meaning. And beware of the lazy references (references that are not yet initialized since the data was not loaded)!&lt;br /&gt;&lt;br /&gt;The trick is that ORM hides all the loading for us. The loading from the DB, and also the saving, is done almost completely transparent. (We need to setup it in the beginning, and from time to time control its transactions, but it's not the SQL Hell (TM) anymore).&lt;br /&gt;&lt;br /&gt;Another thing that SQL forces you is to cut your objects in half, data and separate behaviour. For me data &amp;amp;&amp;amp; behaviour == functions and data. I don't think objects support that in the strict sense. Imagine an atom: while it is composed of protons and electrons, it doesn't make much sense to separate them. It wouldn't be an atom anymore. I really love how the ancient Greeks used to see the atom: uncuttable, something that cannot be divided further.&lt;br /&gt;&lt;wikipedia link=""&gt;&lt;br /&gt;A penguin that can fly it is one messed up penguin. And yes, it's a bird. The penguin itself has data and behaviour bundled with it. This it what makes it an object. It shouldn't have the "fly" method in the first place. (Some will rant, that it can throw an IllegalStateException when trying to fly, but I haven't seen penguins doing that... they just crash and die - MethodNotFound way.)&lt;br /&gt;&lt;br /&gt;Another thing is that there are better languages out there. No java is not the answer. And neither is C#. One of the languages that truly impressed me was... JavaScript. In JavaScript everything is an object. Hierarchies of objects are not bounded to classes, behavior can just be copied, and so on.&lt;br /&gt;&lt;br /&gt;Another issue that was quite hard to do was transaction management. But now, in EJB3 for example, all you need to do is to annotate a method, and there you go, you have a transaction - furthermore, implicitly all the methods of an EJB (EJB == Pojo spelled funny in the EJB3 slang) are services. This transaction also is bounded to the EntityManager (the cool name that is used in the EJB world for the ORM service), so whatever things you add to the entity manager or remove they are persisted automatically.&lt;br /&gt;&lt;br /&gt;AspectJ allows you to define objects that will be called in a more flexible way that the normal method invoke, making transaction management a much simpler issue. (on AspectJ I will have a distinct talk).&lt;br /&gt;&lt;br /&gt;Furthermore, if you're using JSF (another fancy name for displaying things in the beautiful JEE world), you're binding actual objects to the GUI. Editing a h:inputText would have as result setting the property of an object directly. What gets even neater, with tools like SEAM you can immediately validate things. And it's all in my objects. (By the means of this article I want to thank &lt;a href="http://in.relation.to/user/gavin"&gt;Gavin King&lt;/a&gt;, and I truly think he is a genius for creating Hibernate and Seam, and Brendan Eich - the guy who invented JavaScript, the actual CTO at Mozilla).&lt;br /&gt;&lt;br /&gt;If you're using SEAM, you don't even have to worry about stateless calls, there are conversations that keep track of all your objects and they also integrate the transactions usage.&lt;br /&gt;&lt;br /&gt;Bottom line:&lt;br /&gt;The way I see an object, as an atomic &lt;wikipedia link=""&gt; unit of existence, that has behavior and state (data), and they are inseparable. If you do separate them, there must exist a cleaner way, that doesn't invalidate the whole object concept.&lt;br /&gt;&lt;br /&gt;Object programming is simple, but technology constraints made it difficult, many times canceling the basic features of OOP. Fortunately the wheel of technology is turning.&lt;br /&gt;&lt;br /&gt;PS: &lt;/wikipedia&gt;&lt;/wikipedia&gt;This is pretty much a personal (and as such biased) opinion, made on several years of OOP and non OOP programming, under various languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-2664555112476150077?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/2664555112476150077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=2664555112476150077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2664555112476150077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/2664555112476150077'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/11/my-objects-are-returning.html' title='My objects are returning!'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8634577267814470777</id><published>2008-11-12T07:15:00.000-08:00</published><updated>2008-11-12T07:40:41.245-08:00</updated><title type='text'>Creating a SHA1 hashing function for PostgreSQL 8.3 and Ubuntu 8.04</title><content type='html'>I think everyone needs from time to time this hashing method when it gets&lt;br /&gt;to work with user databases, for maintenance purposes.&lt;br /&gt;&lt;br /&gt;As one who migrated from mysql to postgres - (actually I'm still dual using them)&lt;br /&gt;I was surprised to see this very useful function doesn't exist.&lt;br /&gt;&lt;br /&gt;Don't worry, it's easy to add it.&lt;br /&gt;&lt;br /&gt;On the terminal we first need to add the cryptographic libraries for postgres.&lt;br /&gt;The easiest way is to add the postgresql contrib, that contains a lot of goodies,&lt;br /&gt;and, of course, our crypto libraries. Also it is in the repository already.&lt;br /&gt;&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-size:85%; font-family : courier; font-weight: bold"&gt;$ sudo apt-get install postgresql-contrib-8.3&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The next step would be exporting the cryptographic methods (except sha1 unfortunatelly)&lt;br /&gt;into the template from where each newly created database is derived:&lt;br /&gt;&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-family: courier new;font-size:85%;font-family : courier; font-weight: bold" &gt;$ sudo -u postgres psql template1 &lt; /usr/share/postgresql/8.3/contrib/pgcrypto.sql&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;(in case you already have existing databases where you would need these functions, just&lt;br /&gt;change template1 to the corresponding database name, e.g.:&lt;br /&gt;&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-size:85%;font-family : courier; font-weight: bold"&gt;$ sudo -u postgres psql proddb &lt; /usr/share/postgresql/8.3/contrib/pgcrypto.sql&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;Now we need to create our sha1 method (I've used the pgadmin3 tool in order to do that,&lt;br /&gt;but you can still use the psql approach for that).&lt;br /&gt;As you can see the actual work is done by the more generic "DIGEST" method - which&lt;br /&gt;unfortunatelly returns a bytea, and converted to a string by the "ENCODE" method.&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-family: courier new;font-size:85%;font-family : courier; font-weight: bold" &gt;&lt;br /&gt;CREATE OR REPLACE FUNCTION sha1(bytea)&lt;br /&gt;  RETURNS character varying AS&lt;br /&gt;$BODY$&lt;br /&gt;BEGIN&lt;br /&gt;RETURN ENCODE(DIGEST($1, 'sha1'), 'hex');&lt;br /&gt;END;&lt;br /&gt;$BODY$&lt;br /&gt;  LANGUAGE 'plpgsql'&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you want this method to be in every new table from now on, you could put it in some file&lt;br /&gt;(let's say sha1.sql) and run it against the template1.&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-size:85%; font-family : courier; font-weight : bold"&gt;&lt;br /&gt;$ sudo -u postgres psql template1 &lt; ~/sha1.sql&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;After that, a simple&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-size:85%;font-family : courier; font-weight: bold"&gt;&lt;br /&gt;select sha1('test')&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;should return as expected:&lt;br /&gt;&lt;div style="color : white; background : black; padding : 4px"&gt;&lt;span style="font-size:85%;font-family : courier; font-weight: bold"&gt;&lt;br /&gt;a94a8fe5ccb19ba61c4c0873d391e987982fbbd3&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Hoping it helps, I'll end here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8634577267814470777?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8634577267814470777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8634577267814470777' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8634577267814470777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8634577267814470777'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/11/creating-sha1-hashing-function-for.html' title='Creating a SHA1 hashing function for PostgreSQL 8.3 and Ubuntu 8.04'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-5290872325541874725</id><published>2008-10-14T02:29:00.000-07:00</published><updated>2008-10-15T01:48:50.442-07:00</updated><title type='text'>gonsole - a dumb groovy konsole</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.pasicide.org/raptor/gonsole/gonsole.jnlp"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_ie5BPcoUm-I/SPWqI-CUToI/AAAAAAAAACY/I3BQab_51rU/s200/gonsole.png" alt="" id="BLOGGER_PHOTO_ID_5257295211093315202" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;click the image to start the application&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;I am truly impressed by &lt;a href="http://konsole.kde.org/"&gt;konsole&lt;/a&gt; on KDE 3. I am using it all the time. They captured a lot of common use cases that I am finding myself quite often doing. While there are similar approaches on terminals (like gnome-terminal, or even konsole from KDE4), until now I haven't seen something near it.&lt;br /&gt;&lt;br /&gt;The problem is that there are &lt;a href="http://www.microsoft.com/WINDOWS/"&gt;dumb operating systems&lt;/a&gt; out there, where their terminal is a joke. No tabs, no history finding, you can not clear the terminal, no color scheme, so on and so forth... junk - junk - junk.&lt;br /&gt;&lt;br /&gt;Unfortunately I do need to use this weak platform for our JEE development, and I do need to run jboss, thus I've made my own "konsole" in groovy and java. Thus the application is name gonsole... And it's one click away via &lt;a href="http://java.sun.com/javase/technologies/desktop/javawebstart/index.jsp"&gt;java web start&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can click the image to start it. I promise you that it will soon be opensource (most likely GPLv3) on sf.net. I am not opensourcing it immediately since it still has some obvious bugs (e.g. when the shell it's exiting, the tab doesn't close).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-5290872325541874725?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/5290872325541874725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=5290872325541874725' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5290872325541874725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/5290872325541874725'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/10/gonsole-dumb-groovy-konsole.html' title='gonsole - a dumb groovy konsole'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ie5BPcoUm-I/SPWqI-CUToI/AAAAAAAAACY/I3BQab_51rU/s72-c/gonsole.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-7993926914618620144</id><published>2008-06-30T02:23:00.000-07:00</published><updated>2008-06-30T03:01:48.142-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='better'/><category scheme='http://www.blogger.com/atom/ns#' term='static'/><category scheme='http://www.blogger.com/atom/ns#' term='logger'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='singleton'/><category scheme='http://www.blogger.com/atom/ns#' term='utility'/><title type='text'>A Better Static Approach for Utility Classes</title><content type='html'>How many times haven't you've seen code like this in a utility class?&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;StupidLogger {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;log(String what)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(what);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;This kind of code is bringing me to tears since it's almost impossible to reuse it. Imagine now a segment of your application that actually uses that code:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;import static&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea.StupidLogger.log;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;BusinessLogic {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;process()&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log(&lt;font color="#ff00ff"&gt;&amp;quot;hello world!&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;x = &lt;font color="#ff00ff"&gt;5&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;int&lt;/b&gt;&lt;/font&gt;&amp;nbsp;y = &lt;font color="#ff00ff"&gt;7&lt;/font&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log(&lt;font color="#ff00ff"&gt;&amp;quot;x: &amp;quot;&lt;/font&gt;&amp;nbsp;+ x + &lt;font color="#ff00ff"&gt;&amp;quot; + y: &amp;quot;&lt;/font&gt;&amp;nbsp;+ y + &lt;font color="#ff00ff"&gt;&amp;quot; == &amp;quot;&lt;/font&gt;&amp;nbsp;+ (x + y));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;and the corresponding main:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MainApplication {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main(String[]&amp;nbsp;args)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BusinessLogic bl = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;BusinessLogic();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bl.process();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;You're bound to use that version of the StupidLogger for the rest of your life. What's even worse, what if you've already shipped such a version to your client? Most likely he will not redeploy his business jar since it's all fine and dandy. So you need somehow to inject your behaviour into the utility class without changing the business class. Inheritance sounds nice, but here's the trick: &lt;span style="font-weight: bold;"&gt;you can't change via inheritance the static methods&lt;/span&gt;. This is because the actual method call is resolved at compile time. It makes no sense even to have the behaviour from the derived class applied to this one since there is no instance of the class.&lt;br /&gt;&lt;br /&gt;Doing a singleton now looks like a better option, but there is still a drawback: &lt;span style="font-weight: bold;"&gt;you can't use the static import feature if a method it's not static&lt;/span&gt; (quite obvious I would add). Thus your code will look something like: StupidLogger.getInstance().log("foo"). As you might see this is not quite fun.&lt;br /&gt;&lt;br /&gt;IMHO the best approach is combining these two ideas: create a singleton that uses static methods. So the StupidLogger would look like:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;StupidLogger {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;StupidLogger INSTANCE = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;StupidLogger();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;protected&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;logImpl(String what)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(what);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;log(String what)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;INSTANCE.logImpl(what);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;So, if you would want to add behaviour to your utility class, let's say support logging via the java logging mechanisms, you inherit from your utility class:&lt;br /&gt;&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;import&lt;/font&gt;&amp;nbsp;java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CoolLogger &lt;font color="#2e8b57"&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/font&gt;&amp;nbsp;StupidLogger {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Logger log = Logger.getLogger(&lt;font color="#ff00ff"&gt;&amp;quot;com.blogspot.freeopenidea&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#a020f0"&gt;@Override&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;protected&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;logImpl(String what)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log.info(what);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;... and inject it in main&lt;br /&gt;&lt;font face="monospace"&gt;&lt;br /&gt;&lt;font color="#a020f0"&gt;package&lt;/font&gt;&amp;nbsp;com.blogspot.freeopenidea;&lt;br /&gt;&lt;br /&gt;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/font&gt;&amp;nbsp;MainApplication {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StupidLogger.INSTANCE = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;CoolLogger();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;public&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;static&lt;/b&gt;&lt;/font&gt;&amp;nbsp;&lt;font color="#2e8b57"&gt;&lt;b&gt;void&lt;/b&gt;&lt;/font&gt;&amp;nbsp;main(String[]&amp;nbsp;args)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;BusinessLogic bl = &lt;font color="#a52a2a"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/font&gt;&amp;nbsp;BusinessLogic();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bl.process();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Notice that this doesn't requires any changes in the business component, and yet the behaviour is still changed.&lt;br /&gt;&lt;br /&gt;Even if you might consider this article too complex, remember this very important rule of thumb: whenever you blindly use static methods in your utility classes, a small baby rabbit dies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-7993926914618620144?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/7993926914618620144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=7993926914618620144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7993926914618620144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/7993926914618620144'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/06/better-static-approach-for-utility.html' title='A Better Static Approach for Utility Classes'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-1120854704631809650</id><published>2008-06-19T00:31:00.000-07:00</published><updated>2008-06-19T01:41:55.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='gnu'/><category scheme='http://www.blogger.com/atom/ns#' term='choice'/><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='fix'/><title type='text'>Beauty of opensource.</title><content type='html'>Quite recently I had to stumble upon a big project. You know the kind: with &lt;a href="http://java.sun.com/javaee/"&gt;JEE,&lt;/a&gt; a lot of EJBs and a big fat Web and Integration tiers (and a lot of other fancy names). The funny thing is that my Eclipse IDE was cluttered with all of these distinct projects, one for Web, one for Business, one for Model, one for Integration, a distinct one for Security, another one for tests and... I hope I haven't missed any of it.&lt;br /&gt;&lt;br /&gt;So when I had to edit something (let's say the omnipresent Client) I'll had to edit several files, spanning multiple projects but with the same goal. I'll have the clientHome.jsp, clientQuery.jsp (Web project), ClientRepository.java and it's implementation ClientRepositoryEJB (Integration tier project), ClientService.java, ClientServiceEJB.java (Business tier), Client.java (Model) and ClientTest.java (tests).&lt;br /&gt;&lt;br /&gt;The Projects view tend to look like this:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_ie5BPcoUm-I/SFoT_4110_I/AAAAAAAAAA8/SGwLL1cLJLc/s1600-h/cet3.png"&gt;&lt;img style="border: 1px solid black; margin: 0pt 10px 10px 0pt; padding: 4px; float: left; cursor: pointer;" src="http://bp0.blogger.com/_ie5BPcoUm-I/SFoT_4110_I/AAAAAAAAAA8/SGwLL1cLJLc/s200/cet3.png" alt="" id="BLOGGER_PHOTO_ID_5213501506945668082" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;This is still looking quite fun since I've added on purpose only two classes on the model so you could get where I'm going. Imagine that number would be 20 (you do the math). You would have to scroll miles of pixels just to get to that test file, or resource from the web project. You couldn't even see that there were more projects if a fat package, with a lot of java sources, would be opened.&lt;br /&gt;&lt;br /&gt;So you would have to remember and use strong naming conventions so you could use the Eclipse's native Ctrl+Shift+R shortcut.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_ie5BPcoUm-I/SFoWUoCXR1I/AAAAAAAAABU/HzuRLKyqqt8/s1600-h/cet4.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; float: right;" src="http://bp1.blogger.com/_ie5BPcoUm-I/SFoWUoCXR1I/AAAAAAAAABU/HzuRLKyqqt8/s200/cet4.png" alt="" id="BLOGGER_PHOTO_ID_5213504062235297618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;What I would want is something more like the image on the right. I want to group the resources associated with a concept in my own way. Heck, I can even want sometimes the same file to be present under multiple logical groups - a thing impossible in Eclipse (to my knowledge) without creating a link in the Projects View and cluttering even more (!!). The logical groups can structure my thinking - the project view not so much (maybe only at the architecture/component level).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;MagicGroup&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Long story short, I've got really bored to do this scrolling exercise over and over again at my last job. So I've decided to try and build my own Eclipse plugin that can group files by their logic and not by the filesystem.&lt;br /&gt;&lt;br /&gt;Apparently it's not that hard and I'm proud to present you &lt;a href="http://sourceforge.net/projects/magicgroup"&gt;MagicGroup,&lt;/a&gt;&lt;br /&gt;my attempt of fixing this project mess. Released under BSD and GPL3 licences (you pick which one) it's very easy to run it (just copy the &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=224162&amp;amp;package_id=271060"&gt;magicgroup jar from sourceforge&lt;/a&gt; into the plugins folder and restart Eclipse). After it's installed go to Window-&gt;Show View-&gt;Other and pick it.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_ie5BPcoUm-I/SFoWDXCq1gI/AAAAAAAAABE/Wy6VFXZm9j8/s1600-h/cet2.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_ie5BPcoUm-I/SFoWDXCq1gI/AAAAAAAAABE/Wy6VFXZm9j8/s200/cet2.png" alt="" id="BLOGGER_PHOTO_ID_5213503765615400450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So where is the beauty of the opensource in all this? The truth be told, I couldn't have done it without the tremendous amount of code out there for the Eclipse platform - which I did use as documenting reference. (Google also seems to be a nice friend when it comes to search for various topics.)&lt;br /&gt;&lt;br /&gt;The plugin I wrote itself can be used on any Eclipse (3.3 tested) distro. Let's say you use Aptana for editing PHP, or Eclipse with JSEdit for JavaScript, or just Eclipse with JEE like I do: it doesn't matter. It's very easy to cherry pick  your plugins and add value to your Eclipse.&lt;br /&gt;&lt;br /&gt;So you can consider this contribution as my humble thank you, back to the Eclipse community.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-1120854704631809650?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/1120854704631809650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=1120854704631809650' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1120854704631809650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/1120854704631809650'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2008/06/beauty-of-opensource.html' title='Beauty of opensource.'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_ie5BPcoUm-I/SFoT_4110_I/AAAAAAAAAA8/SGwLL1cLJLc/s72-c/cet3.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-9101224458007692715</id><published>2007-12-14T05:12:00.000-08:00</published><updated>2007-12-16T22:38:36.157-08:00</updated><title type='text'>Test Driven Development</title><content type='html'>&lt;span style="font-size:180%;"&gt;What It Is (or Abstract)&lt;/span&gt;&lt;p style="margin-bottom: 0in;"&gt;It is a development method that states test code should be written before the actual program code. In theory (and also in practice)it leverages code development by exposing actual functionality than fuzzy specification.&lt;/p&gt; &lt;span style="font-size:180%;"&gt;Why it is used&lt;/span&gt; &lt;p style="margin-bottom: 0in;"&gt;Many times when the domain of the problem is getting contoured, there are parts of the model that is to be modeled (or parts from the processes of the business process) which are not clearly specified. How the object(s) should be created?, how can we will get the actual feedback if a constraint is invalidated?, how would objects actually behave in their relations with each other&lt;sup&gt;&lt;a class="sdfootnoteanc" name="sdfootnote1anc" href="http://www.blogger.com/post-edit.g?blogID=1539752288286250641&amp;amp;postID=9101224458007692715#sdfootnote1sym"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/sup&gt;?.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;By writing the tests upfront, the specification can be clarified of any “uncertain” aspects. Not only that the specification is clarified, but it is also possible for the developers to check the tests as a mean of usage pattern, by seeing the functionality exposed from the model. You can have a hands on experience with the code to be developed and you get a greater insight of how it is supposed to work.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Another thing is that UML, and the actual initial design can not possibly capture the full complexity of the problem in all of its use cases, thus making the domain incomplete even from the early stages of development.&lt;/p&gt; &lt;span style="font-size:180%;"&gt;How it is done&lt;/span&gt; &lt;p style="margin-bottom: 0in;"&gt;The tests are written as if the code to be tested is already there. For example, assuming that we would have a specification that states the following: “a UserGroup has one or more User(s)”, then the test could look like this:&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt;      &lt;p style="margin-bottom: 0in; line-height: 150%;"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; SomeTest {&lt;br /&gt;[...]&lt;br /&gt;@Test &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;public void&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; testMethod() {&lt;br /&gt; UserGroup ug = &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; UserGroup();&lt;br /&gt; assertTrue(ug.userCount() &gt; 0); &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;// it should be one or more&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in; line-height: 150%;" align="right"&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;    &lt;span style="font-family:Times,Times New Roman,serif;"&gt;&lt;span style="font-size:85%;"&gt;We can even expect how many users should be on a newly created UserGroup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-bottom: 0in; line-height: 150%;"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;assertTrue(ug.userCount()) == 2);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in; line-height: 150%;" align="right"&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;    &lt;span style="font-family:Times,Times New Roman,serif;"&gt;&lt;span style="font-size:85%;"&gt;We can now see that the specification is more refined.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in; line-height: 150%;" align="right"&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;&lt;span style="font-family:Times,Times New Roman,serif;"&gt;&lt;span style="font-size:85%;"&gt;Not only that an UserGroup has at least one users when it is newly created, but we can even add more constraints.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;     &lt;p style="margin-bottom: 0in; line-height: 150%;"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; (User u : ug.getUsers()) {&lt;br /&gt; assertTrue( u.getName().equals(“admin”) ||&lt;br /&gt;         u.getName().equals(“moderator”)&lt;br /&gt;         );&lt;br /&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0in; line-height: 150%;" align="right"&gt;&lt;span style="color: rgb(0, 0, 128);"&gt;    &lt;span style="font-family:Times,Times New Roman,serif;"&gt;&lt;span style="font-size:85%;"&gt;And we even know that one of the default users is admin and the other one it is the moderator.&lt;br /&gt;Furthermore, fully check the specification.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;        &lt;p style="margin-bottom: 0in; line-height: 150%;"&gt;    &lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;ug.removeUser(ug.getUsers().get(0)); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;// blindly remove the first user&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;assertTrue(ug.userCount() == 1);&lt;br /&gt;&lt;b&gt;  &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;ug.removeUser(ug.getUsers().get(0)); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;// blindly remove the second user&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;assertTrue(ug.userCount() == 0);&lt;br /&gt;&lt;b&gt;try&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; {&lt;br /&gt; ug.removeUser(ug.getUsers().get(0)); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;// remove the first user again&lt;/i&gt;&lt;/span&gt;&lt;br /&gt; assertTrue(false); &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;i&gt;// this is unreachable&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;} &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt; (RemoveUserException e) {&lt;br /&gt; // ...&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;span style="font-family:Courier New,monospace;"&gt;&lt;span style="font-size:85%;"&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;At the end of our test, our specification is more clear about what should happen when we create a new UserGroup, how we can access the Users inside (notice that the specification didn't said at all how this should be done), and the obvious thing that the code we just wrote can be used now as a regression test.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;As I've said before, this code is written as the code to be tested already exists. What that means in plain English is that the code won't even compile in the first phase. (remember, both of the classes User and UserGroup are not existing at all). For this, it would be a good thing to remove from your IDE the automatically build feature. Otherwise your screen will be cluttered with red lines stating errors which you can safely ignore for now.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Now the test becomes a part of the specification itself, and it should be delivered as such.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;There are at least three issues to consider though:&lt;/p&gt; &lt;ol&gt;&lt;li&gt;&lt;p style="margin-bottom: 0in;"&gt;What happens when multiple  developers are writing test cases for different parts of the  model?&lt;br /&gt;The main problem that can occur in this case is that of  two developers messing up the signatures of one object. In our  example this could happen if one of the developers would consider  that the User's name should be retrieved with getUserName instead of  getName. Now there would be two methods with the same role -  redundant code and a code that smells like danger.&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0in;"&gt;What if the specification gets  changed – either by plain internal refactoring, or the customer  changing the requirements?&lt;br /&gt;The tests need to be rewritten. Even  if it might look hard in the beginning, they are the guarantee that  our model is actually implementing the specification given, and not  just a bunch of classes that reminds us of some old, lost inside the  Middle Earth since the rise of Sauron, specification.&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0in;"&gt;After the test, it is highly  possible that the specification will be altered. Should these  changes be published back into the original document?&lt;br /&gt;This is a  tricky question, and it all goes down to common sense. For the  UserGroup example I think it should update the document by writing  explicitly that the UserGroup creates by default 2 users, admin and  moderator. It is important to expect this when creating a new  UserGroup, and it is part of its contract. All the other changes,  like how to access the User name, how to get the list of users from  the UserGroup, and such like it, are irrelevant and they will  overload the documentation with useless details.   &lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;span style="font-size:180%;"&gt;Bottom line&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Advantages&lt;/span&gt;&lt;p style="margin-bottom: 0in;"&gt;We have at least the following guarantees:&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;The code doesn't break.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;The code is functionally correct in all of its use cases.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;The code behavior can be verified when change inside the code occurs  - extensions or just bug fixing.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;span style="font-size:100%;"&gt;It adds value to the developers work by providing clearer requirements and usage scenarios.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;Disadvantages&lt;/span&gt;&lt;p style="margin-bottom: 0in;"&gt;&lt;span style="font-size:100%;"&gt;Initially it may look cumbersome to write tests without any class since you don't see any functionality being added to the project.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Changes in the project model (or services) needs to be also reflected into these tests. This may lead to fear to refactoring, even if such a refactoring is much needed, if it would impact a big code base, since the initial code of the tests will be most likely thrown.&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;You have a new project to take care of (the set of tests is a project in its own right&lt;sup&gt;&lt;a class="sdfootnoteanc" name="sdfootnote2anc" href="http://www.blogger.com/post-edit.g?blogID=1539752288286250641&amp;amp;postID=9101224458007692715#sdfootnote2sym"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt; &lt;span style="font-size:180%;"&gt;Appendix&lt;/span&gt; &lt;p style="margin-bottom: 0in;"&gt;Another place where TDD can be used with success is, in my opinion, when using interfaces of products or modules which are developed in parallel. What happens now, is that we have the interfaces of the other module we want to use, we have their documentation written down, but we have no usage pattern. So we will write some stubs that implement the service we are using, and create the tests for the service. When the actual service is used instead of the stubs, the tests should be passing. Otherwise it means we either had some wrong assumptions regarding the module we just used, either the actual module was delivered with bugs into our side.&lt;/p&gt; &lt;div id="sdfootnote1"&gt;  &lt;p style="margin-bottom: 0in;"&gt;&lt;a class="sdfootnotesym" name="sdfootnote1sym" href="http://www.blogger.com/post-edit.g?blogID=1539752288286250641&amp;amp;postID=9101224458007692715#sdfootnote1anc"&gt;1&lt;/a&gt;There  are methods of doing so directly in the UML (sequence diagrams, for  example) but they are hard to draw and hard to be comprehended at a  quick look.&lt;/p&gt; &lt;/div&gt; &lt;div id="sdfootnote2"&gt;  &lt;p style="margin-bottom: 0in;"&gt;&lt;a class="sdfootnotesym" name="sdfootnote2sym" href="http://www.blogger.com/post-edit.g?blogID=1539752288286250641&amp;amp;postID=9101224458007692715#sdfootnote2anc"&gt;2&lt;/a&gt;  Even though it doesn't need its own tests, since it would make  almost no sense.&lt;/p&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-9101224458007692715?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/9101224458007692715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=9101224458007692715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/9101224458007692715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/9101224458007692715'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/12/test-driven-development.html' title='Test Driven Development'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-3567792828333312258</id><published>2007-08-12T18:34:00.000-07:00</published><updated>2007-08-17T13:34:43.121-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='cpp'/><title type='text'>The right tool, for the right job, part 1</title><content type='html'>Today I am going to speak about programming languages and I will do a quick comparison between bash, perl, python, c++ and java, or as some may like to say dynamic vs strong typed languages.&lt;br /&gt;&lt;br /&gt;Many people, especially those exposed to only one operating system, tend to have a limited knowledge about dynamic languages and they are mostly stuck with c++ or java. Even though these languages are great, dynamic languages permit you to do rapid prototyping and to have faster development cycles (since in most of the cases, at the time of writing, the program is already compiled and deployed).&lt;br /&gt;&lt;br /&gt;Ok, so let's get it started:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;bash&lt;/span&gt;&lt;br /&gt;bash is the shell you're most likely already using if you're using a Linux distribution or a Mac. And, if you didn't knew, it's also a programming language. In my opinion this language is perfect for basic maintainance tasks (e.g. removing all backup files from subfolders, and packing the current folder).&lt;br /&gt;&lt;br /&gt;It could be written as simple as:&lt;blockquote&gt; &lt;span style="font-family:courier new;"&gt;#!/usr/bin/env bash&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# find and remove all ending with ~&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;find . -name \*~ -type f | xargs rm&lt;br /&gt;# archive the current folder into archive.tar.gz&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;tar -cf - . | gzip &gt; ../archive.tar.gz&lt;/span&gt; &lt;/blockquote&gt;Variables are dynamic:&lt;br /&gt;&lt;blockquote&gt;a="foo"&lt;br /&gt;echo "variable a is $a"&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;perl&lt;/span&gt;&lt;br /&gt;perl is the language of choice if you want to do log parsing, applying regular expressions over mountains of text or one way code generators.&lt;br /&gt;For example to implement grep's functionality you need 4 (four) lines of code.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;#!/usr/bin/env perl&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$search = shift;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;while (&lt;&gt;) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; print $_ if (/$search/);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;Code generators can be done as fast:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;#!/usr/bin/env perl&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$class = "Foo"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$member = "x"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;print &amp;lt;&amp;lt;CPPCONTENT;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// default constructor&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;${class}::${class}() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;    $member = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int ${class}::get_${member}() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;    return $member;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;${class}::set_${member}(int value) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;    $member = value;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CPPCONTENT &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;And notice that the change will be done in place.&lt;br /&gt;&lt;br /&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&lt;span style="font-weight: bold;"&gt;python&lt;/span&gt;&lt;br /&gt;Python is perl with steroids. While the regular expressions support and reading into the default $_ is not there (this makes while(&lt;&gt;) { print $_; } so magic in perl) it has all the other goodies of being dynamic, contains libraries for whatever you can think of, and a very strong support for objects. In Python absolutely everything is an object. I don't know another language to have this - eyther they are limited by being strong typed.&lt;/cppend;&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&lt;span style="font-family:courier new;"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;h = {}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;h['user'] = "BM"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;h['title'] = "Mr."&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;print "Dear %(title)s %(user)s, you are kindly invited to dinner." % h&lt;/span&gt;&lt;/cppend;&gt;&lt;/blockquote&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;Guess what it'll print! Yup, you got it right. More or less like perl in this aspect. But the following is fantastic (try it in IDLE, python's default IDE - if you have installed python, you have IDLE):&lt;/cppend;&gt;&lt;br /&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&lt;/cppend;&gt;&lt;blockquote&gt;&lt;cppend; style="font-family: courier new;" include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&gt;&gt;&gt; class A:&lt;br /&gt;pass&lt;br /&gt;&lt;/cppend;&gt;&lt;br /&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt;&gt; A.x = int()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt;&gt; a = A()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt;&gt; dir (a)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;['__doc__', '__module__', 'x']&lt;/span&gt;&lt;br /&gt;&lt;/cppend;&gt;&lt;/blockquote&gt;&lt;cppend; include="" h="" constructor="" return="" void="" int="" cppend="" funny="" thing="" about="" this="" multiple="" line="" print="" approach="" is="" that="" variable="" s="" value="" will="" replaced="" and="" the="" variables="" can="" also="" be="" arrays="" or=""&gt;Whoaaa... What just happened here. As I told you, in python everything is an object. Hence, to the class A we added a new member (after the class was defined), after we instantiate a, we can see that x is defined. If you don't belive it's a new member, define a new instance of A and assign it values ;).&lt;br /&gt;&lt;br /&gt;Basically, even if you can't extend the primitive types of the language (e.g. add new methods to the str class to better suit you) you still  can change the base  classes of various frameworks you may use.&lt;/cppend;&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_ie5BPcoUm-I/Rr_DHCMMC2I/AAAAAAAAAAs/jXXquYpmkhQ/s1600-h/Screw_Driver_display.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_ie5BPcoUm-I/Rr_DHCMMC2I/AAAAAAAAAAs/jXXquYpmkhQ/s400/Screw_Driver_display.jpg" alt="" id="BLOGGER_PHOTO_ID_5098007828821183330" border="0" /&gt;&lt;/a&gt;As you might already have noticed some parts may look enough "cryptic" already, and it's perfectly normal, no need to be scared. The point is that if you diversify the number of languages you know you will finish your work sooner with less work. Imagine doing the bash example of removing all backup files in java and you'll see that it would have taken ages to complete it.&lt;br /&gt;&lt;br /&gt;In bash it's exactly one line.&lt;br /&gt;&lt;br /&gt;Or the code generation from perl. In how many lines you can do it (except python)? Actually, in perl, you're almost writing the final program. This is why it's the main language I am using when I am developing one way code generators for classes that look mostly the same but have some weird logic that I can't convince my IDE to do it.&lt;br /&gt;&lt;br /&gt;Bottom line: no programming language is an island, and there isn't such a language to catch all the needs of millions of programmers out there for the billions of tasks they must make. Diversify your knowledge.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-3567792828333312258?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/3567792828333312258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=3567792828333312258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3567792828333312258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/3567792828333312258'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/08/right-tool-for-right-job-part-1.html' title='The right tool, for the right job, part 1'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_ie5BPcoUm-I/Rr_DHCMMC2I/AAAAAAAAAAs/jXXquYpmkhQ/s72-c/Screw_Driver_display.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-806019560374598503</id><published>2007-07-26T17:11:00.000-07:00</published><updated>2007-07-26T18:18:16.072-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drm'/><category scheme='http://www.blogger.com/atom/ns#' term='corporate'/><category scheme='http://www.blogger.com/atom/ns#' term='corporations'/><category scheme='http://www.blogger.com/atom/ns#' term='copyright'/><category scheme='http://www.blogger.com/atom/ns#' term='choice'/><category scheme='http://www.blogger.com/atom/ns#' term='free'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>The DRM failure</title><content type='html'>Hi again... I haven't wrote in a while because I was quite busy. I am developing something and I hope soon (2-3 months at least) I will be able to announce the project more or less ready.&lt;br /&gt;&lt;br /&gt;Today I am going to talk about DRM. What is DRM? Well, DRM stands for &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt;igital &lt;span style="font-weight: bold;"&gt;R&lt;/span&gt;ights &lt;span style="font-weight: bold;"&gt;M&lt;/span&gt;anagement and is a way for some corporations (usually content providers - a.k.a. multimedia producers, etc.) to control the way you use the media you purchase from them. Allmost all serious music producers are using it in order to distribute their music. What DRM enforces is how you can (not) use your music, on which devices you can copy it and how many times, and so on.&lt;br /&gt;&lt;br /&gt;For example, you can't download an MP3 and play it on every USB device? Why? Because that would defeat the purpose of DRM. You would be then able to copy that content to other devices DRM free and eventually share it with your friends.&lt;br /&gt;&lt;br /&gt;Basically DRM has only one reason behind it: not to trust you. In theory if you are a pirate it will be very hard for you to distribute the "stolen" music to other peers. In practice if you really want to steal music you have google.com, altavista, and good old bittorrent sites. And because there are so many file sharing sites, the whole purpose of DRM has backfired against regular users who do actually buy music.&lt;br /&gt;&lt;br /&gt;For example I buy my music - for some people this may sound crazy, and quite recently I've discovered Seven Places (a very cool true Christian band - or exband more accurately said) and Jeremy Camp (another Christian singer). And I've decided to buy them. Unfortunately I am living in Cyprus and amazon.co.uk doesn't ship in Cyprus. So I decided to buy their songs online.&lt;br /&gt;&lt;br /&gt;I couldn't find &lt;span style="font-weight: bold;"&gt;any&lt;/span&gt; shop to sell that song without DRM. Why I explicitly want that? Because I am using Linux and I don't want to switch to a worse operating system because of some trifle reason. Why would I have to give up my liberties (or at least a part of it) because some corporations are incapable to trust me? I don't want to be limited in copying my music just to a few "compatible devices" as they name them or to use Windows XP. After all we pay for those songs, and we should be in charge, demanding what rights we want, not the other way around.&lt;br /&gt;&lt;br /&gt;I want to be able to listen my music on my phone, on my mp3 player, burn CDs for my car (eventually, since I don't have a car) and also play them on my PC. Otherwise, online radio, youtube and bittorrent will be my music provider of choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-806019560374598503?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/806019560374598503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=806019560374598503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/806019560374598503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/806019560374598503'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/07/drm-failure.html' title='The DRM failure'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-8423464952809088331</id><published>2007-06-26T10:31:00.000-07:00</published><updated>2007-06-26T11:12:37.119-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='four'/><category scheme='http://www.blogger.com/atom/ns#' term='gnu'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='stallman'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>Four Freedoms</title><content type='html'>I always loved software. Actually the whole process of creating from nothing (bits and bytes) something. Something which you can't possibly touch, but yet is being able to display various shapes and colors, or being able to print and so on.&lt;br /&gt;&lt;br /&gt;And to some extent it looks and it behaves "magic". For no apparent reason, it takes sometimes less then a second from the moment you clicked print until the engine from the printer starts working and in the end you have a beautiful picture displayed on a sheet of paper.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_ie5BPcoUm-I/RoFT0KN3SNI/AAAAAAAAAAk/-gQ-a6Q-W-M/s1600-h/Screenshot-Print.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_ie5BPcoUm-I/RoFT0KN3SNI/AAAAAAAAAAk/-gQ-a6Q-W-M/s400/Screenshot-Print.png" alt="" id="BLOGGER_PHOTO_ID_5080434010211436754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;But what if I would tell you that at least 7 (seven) protocols were used for that &lt;span style="font-weight: bold;"&gt;single&lt;/span&gt; piece of paper to go from your PC or MAC, to your printer to get printed? You have PS (or PostScript, the language that your printer knows), most likely Physical, Ethernet, IP and TCP (all from ISO/OSI protocol - more or less) to move your image over the network, and your image was most likely GZipped so it would reduce network traffic and was encoded let's say as PNG.&lt;br /&gt;&lt;br /&gt;Can you imagine? All this complexity is completely transparent for you. You don't have to know&lt;br /&gt;nothing about it, in order to print your graphic. It's just amazing.&lt;br /&gt;&lt;br /&gt;But there is something you must know about it...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;It's All Freedom... or Not.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think anyone should have the following freedoms when it comes to whatever software they use:&lt;br /&gt;1. The freedom to run the program, for any purpose (freedom 0).&lt;br /&gt;2. The freedom to study how the program works, and adapt it to your needs (freedom 1). Access to the source code is a precondition for this.&lt;br /&gt;3. The freedom to redistribute copies so you can help your neighbor (freedom 2).&lt;br /&gt;4. The freedom to improve the program, and release your improvements to the public, so that the whole community benefits. (freedom 3). Access to the source code is a precondition for this.&lt;br /&gt;&lt;br /&gt;These are by no means original ideas. These ideas were stated first by Richard Stallman a man who saw a danger in the way that software is done. Actually, these days, the software is done in such a way that it's meant not only not to give freedoms, but to enslave its users. Imagine you will be forced to use only one operating system, or better even, cook only one recipe. Sudden change of subject? Maybe. but here's another quote from Stallman:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt; Imagine how angry everyone who cooks would be if some day the government says "From now on, if you share or change a recipe, we're going to call you a pirate, we're going to compare you with people who attack ships, and we're going to put you in prison for years because that's forbidden cooperation".  Imagine the anger that there would be.  That anger is at the basis of the free software movement too.  We want to have freedom in using our computers. &lt;/blockquote&gt;It does make sense, isn't it?&lt;p style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Does Freedom Exists?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;I dare to present to you, today, the freedom 0 in a very known operating system, Ubuntu:&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_ie5BPcoUm-I/RoFTYKN3SMI/AAAAAAAAAAc/m1skODZK8rM/s1600-h/freedom+0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_ie5BPcoUm-I/RoFTYKN3SMI/AAAAAAAAAAc/m1skODZK8rM/s400/freedom+0.png" alt="" id="BLOGGER_PHOTO_ID_5080433529175099586" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;There it is, right there... the freedom 0. You can take whatever software you want and use it in whatever way you want. No strings attached. As you can see though, freedom it's all about empowering you as final user in being able to choose what software you want, and to be able to share it with your friends.&lt;/p&gt;&lt;p&gt;Unfortunately most systems nowadays are not at all like this. Most likely if you bought them, you can't share them with your friends, you don't have access to the source code (you, or your geeky friends).&lt;/p&gt;&lt;p&gt;Now imagine that there is an Operating System that empowers you with one click in getting the latest free software you can use. I am writing from it, about it. I am creating on it. I am sharing it with you. No restrictions, no boundaries.&lt;/p&gt;&lt;a href="http://www.ubuntu.com"&gt;Freedom starts here: ubuntu&lt;/a&gt;&lt;a href="http://www.ubuntu.com"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-8423464952809088331?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/8423464952809088331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=8423464952809088331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8423464952809088331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/8423464952809088331'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/06/four-freedoms.html' title='Four Freedoms'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_ie5BPcoUm-I/RoFT0KN3SNI/AAAAAAAAAAk/-gQ-a6Q-W-M/s72-c/Screenshot-Print.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6742100392937104093</id><published>2007-06-22T12:33:00.000-07:00</published><updated>2007-06-22T12:52:42.423-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.2'/><category scheme='http://www.blogger.com/atom/ns#' term='build'/><category scheme='http://www.blogger.com/atom/ns#' term='not_configured'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='rc.local'/><category scheme='http://www.blogger.com/atom/ns#' term='/etc/'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='fix'/><title type='text'>Fixing vmware for ubuntu.2</title><content type='html'>After I've rebooted my machine I've realized that again for some unknown reason the not_configured file it's still in /etc/vmware even if vmware service started successfully. This will give you the following:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;vmware is installed, but it has not been (correctly) configured&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for this system. To (re-)configure it, invoke the following command:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;/usr/bin/vmware-config.pl.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;each time you want to run vmware. Even if you do vmware-config until the very infinite, it still won't work and fail each time with the same error. This is a "known bug"  - at least by me - and it reduces to the following axiom:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;"If and only if vmware services are up and running, and the not_configured file it's still existing in /etc/vmware then you can safely remove it."&lt;/blockquote&gt;While I can not guarantee it, it's a fact for me proven by practice for many-many times before. So I  gave it an aid in /etc/rc.local so I won't have to remove it every time. Now my rc.local file contains also:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;rm -f /etc/vmware/not_configured&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;Don't forget, the vmware services should be up and running and only vmware program failing to launch.&lt;br /&gt;&lt;br /&gt;You would do anything to stop me using your product, ain't it VMware, ain't it?... eh? Just kidding. As a matter of fact is that VMware Workstation is a great product, since it has very good driver support and hence performance on guest systems, and very less load on the host.&lt;br /&gt;&lt;br /&gt;I am quite happy with it running my SVN server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6742100392937104093?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6742100392937104093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6742100392937104093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6742100392937104093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6742100392937104093'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/06/fixing-vmware-for-ubuntu2.html' title='Fixing vmware for ubuntu.2'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-4966031731108167105</id><published>2007-06-20T21:50:00.000-07:00</published><updated>2007-09-14T12:40:22.038-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='build'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='patch'/><category scheme='http://www.blogger.com/atom/ns#' term='diff'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='fix'/><title type='text'>Fixing vmware for ubuntu</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_ie5BPcoUm-I/RnoJ4aN3SLI/AAAAAAAAAAU/ue2M7R0c6BI/s1600-h/vmware-ubuntu.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_ie5BPcoUm-I/RnoJ4aN3SLI/AAAAAAAAAAU/ue2M7R0c6BI/s400/vmware-ubuntu.png" alt="" id="BLOGGER_PHOTO_ID_5078382394528450738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I've updated to the brand new latest version of Ubuntu, as I like to be in shape with the latest trends when it comes to IT in general, and Ubuntu in special. After I've update my kernel to linux-server-2.6.20.16 suddenly I've realized that vmware wouldn't like to start.&lt;br /&gt;&lt;br /&gt;This is a very unfortunate event since on that "machine" I am holding my SVN server... so if it's down, then... no work can be done.&lt;br /&gt;&lt;br /&gt;I did like any guy would do in these circumstances:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;/usr/bin/vmware-config.pl&lt;/blockquote&gt;&lt;/span&gt; &lt;/span&gt;but failed with this error:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;Using 2.6.x kernel build system.&lt;br /&gt;make: Entering directory `/tmp/vmware-config0/vmmon-only'&lt;br /&gt;make -C /lib/modules/2.6.20-16-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules&lt;br /&gt;make[1]: Entering directory `/usr/src/linux-headers-2.6.20-16-generic'&lt;br /&gt;CC [M]  /tmp/vmware-config0/vmmon-only/linux/driver.o&lt;br /&gt;In file included from /tmp/vmware-config0/vmmon-only/linux/driver.c:80:&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: error: expected declaration specifiers or ‘...’ before ‘compat_exit’&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: error: expected declaration specifiers or ‘...’ before ‘exit_code’&lt;br /&gt;/tmp/vmware-config0/vmmon-only/./include/compat_kernel.h:21: warning: type defaults to ‘int’ in declaration of ‘_syscall1’&lt;br /&gt;make[2]: *** [/tmp/vmware-config0/vmmon-only/linux/driver.o] Error 1&lt;br /&gt;make[1]: *** [_module_/tmp/vmware-config0/vmmon-only] Error 2&lt;br /&gt;make[1]: Leaving directory `/usr/src/linux-headers-2.6.20-16-generic'&lt;br /&gt;make: *** [vmmon.ko] Error 2&lt;br /&gt;make: Leaving directory `/tmp/vmware-config0/vmmon-only'&lt;br /&gt;Unable to build the vmmon module.&lt;/span&gt;&lt;/blockquote&gt;I took a quick look at the source code and I couldn't possibly find were the compat_exit is defined... and... I've commented the offending line which was also a static symbol, that I don't think it was used anywhere -VMware, take care - (if it was used I would fail at compile time). I've built it and... tadaaa.. it works.&lt;br /&gt;&lt;br /&gt;So, here goes my fix... If you are experiencing the same problem, you would need these two files:&lt;table border="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="1"&gt;&lt;a href="http://freeopenidea.googlegroups.com/web/vmware-config.diff"&gt;&lt;img src="http://bp3.blogger.com/_ie5BPcoUm-I/RurcYqflL2I/AAAAAAAAAA0/ioyf4y-YrHU/s200/ascii.png" alt="" id="BLOGGER_PHOTO_ID_5110139043486969698" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;a href="http://freeopenidea.googlegroups.com/web/vmware-config.diff"&gt;vmware-config.diff&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="1"&gt;&lt;a href="http://freeopenidea.googlegroups.com/web/vmfix.diff"&gt;&lt;img src="http://bp3.blogger.com/_ie5BPcoUm-I/RurcYqflL2I/AAAAAAAAAA0/ioyf4y-YrHU/s200/ascii.png" alt="" id="BLOGGER_PHOTO_ID_5110139043486969698" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;a href="http://freeopenidea.googlegroups.com/web/vmfix.diff"&gt;vmfix.diff&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Download them to be located both in the same folder.&lt;br /&gt;&lt;br /&gt;Then, you will need as root (or sudo) to patch your vmware-config from /usr/bin like that:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;blockquote&gt;# patch /usr/bin/vmware-config.pl vmware-config.diff&lt;/blockquote&gt;&lt;/span&gt;then in the same folder where the files are (especially the vmfix.diff)...&lt;br /&gt;&lt;blockquote  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;# /usr/bin/vmware-config.pl&lt;/span&gt;&lt;/blockquote&gt;... and just sit back and relax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-4966031731108167105?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/4966031731108167105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=4966031731108167105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4966031731108167105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/4966031731108167105'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/06/fixing-vmware-for-ubuntu.html' title='Fixing vmware for ubuntu'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_ie5BPcoUm-I/RnoJ4aN3SLI/AAAAAAAAAAU/ue2M7R0c6BI/s72-c/vmware-ubuntu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1539752288286250641.post-6527864222676424194</id><published>2007-06-13T06:43:00.000-07:00</published><updated>2007-06-13T06:44:53.382-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='start'/><category scheme='http://www.blogger.com/atom/ns#' term='begin'/><category scheme='http://www.blogger.com/atom/ns#' term='initial'/><title type='text'>Here it goes...</title><content type='html'>It had begun....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1539752288286250641-6527864222676424194?l=freeopenidea.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://freeopenidea.blogspot.com/feeds/6527864222676424194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1539752288286250641&amp;postID=6527864222676424194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6527864222676424194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1539752288286250641/posts/default/6527864222676424194'/><link rel='alternate' type='text/html' href='http://freeopenidea.blogspot.com/2007/06/here-it-goes.html' title='Here it goes...'/><author><name>BM</name><uri>http://www.blogger.com/profile/06767471412754309248</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://1.bp.blogspot.com/_ie5BPcoUm-I/SLuOrPcXz3I/AAAAAAAAACA/KNZubOtegro/S220/me.png'/></author><thr:total>0</thr:total></entry></feed>
