<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;CUYCSXw6fCp7ImA9WhBaEE4.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503</id><updated>2013-05-20T02:59:28.214-04:00</updated><category term="Toronto" /><category term="Unit testing" /><category term="Pascal Script" /><category term="Template Method" /><category term="throttling" /><category term="immigration" /><category term="Technorati" /><category term="iterative" /><category term="Google AdSense" /><category term="Royal Bank of Canada" /><category term="Royal Bank" /><category term="phone" /><category term="BitTorrent" /><category term="RSS" /><category term="factorial" /><category term="TDD" /><category term="society" /><category term="refugees" /><category term="torrent" /><category term="Delphi" /><category term="TD" /><category term="The Brick" /><category term="Search Engine Optimization" /><category term="Canada" /><category term="call cuba" /><category term="Pascal Programming" /><category term="Vidalia" /><category term="Monthly Fee" /><category term="ING DIRECT" /><category term="TFSA" /><category term="Dynadot" /><category term="Test Driven Development" /><category term="newcomers" /><category term="BitTorrent blocking" /><category term="URL" /><category term="ETECSA" /><category term="XML" /><category term="Blogger" /><category term="Divorce" /><category term="blog search engine" /><category term="SERVICE FEE" /><category term="Object Pascal Programming" /><category term="MultiProduct Rebate" /><category term="AdSense" /><category term="InfoLinks" /><category term="DUnit" /><category term="backlinks" /><category term="domain name registrar" /><category term="FEE" /><category term="RBC" /><category term="recursion" /><category term="sitemap" /><category term="Object-Oriented Programming" /><category term="Atom" /><category term="Big-O" /><category term="Twitter" /><category term="I-94 Form" /><category term="Baidu" /><category term="recursive" /><category term="BitTorrent throttling" /><category term="tag" /><category term="VISA" /><category term="Online Banking" /><category term="Indy" /><category term="IDE" /><category term="banking" /><category term="Programming" /><category term="ISP" /><category term="Cuba" /><category term="FireMonkey" /><category term="blog directory" /><category term="Tor" /><category term="Creational Patterns" /><category term="Bank" /><category term="tag cloud" /><category term="Ontario" /><category term="Savings account" /><category term="TopOfBlogs" /><category term="domain" /><category term="Debit Card" /><category term="services" /><category term="Yahoo" /><category term="Design Patterns" /><category term="Tax-Free Savings Account" /><category term="Chequing" /><category term="Internet" /><category term="configure" /><category term="Delphi Programming" /><category term="Behavioral Patterns" /><category term="TD Canada Trust" /><category term="visitor visas" /><category term="blog" /><category term="API" /><category term="Structural patterns" /><category term="Google" /><category term="cell" /><category term="nonimmigrant visas" /><category term="I-94" /><category term="Algorithm" /><category term="tips for immigrants" /><category term="ICANN" /><category term="Bing" /><category term="Computers" /><category term="jobs" /><category term="SEO" /><category term="PageRank" /><category term="EasyWeb" /><category term="Singleton" /><category term="Cubacel" /><category term="immigrant" /><category term="Brick Platinum Card" /><category term="US" /><category term="Macros" /><category term="P2P" /><category term="Pascal" /><category term="Rogers" /><title>Yanniel's notes</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.yanniel.info/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/yanniel-notes" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="yanniel-notes" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEINQ3k4cSp7ImA9WhBWE0Q.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-2880743192040761968</id><published>2013-04-07T23:38:00.001-04:00</published><updated>2013-04-07T23:43:12.739-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-07T23:43:12.739-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Canada" /><category scheme="http://www.blogger.com/atom/ns#" term="Chequing" /><category scheme="http://www.blogger.com/atom/ns#" term="Bank" /><category scheme="http://www.blogger.com/atom/ns#" term="banking" /><category scheme="http://www.blogger.com/atom/ns#" term="ING DIRECT" /><title>How to open a checking account at ING DIRECT</title><content type="html">&lt;div style="text-align: justify;"&gt;
Everything at ING DIRECT is done online… opening a checking account is no different: you can do it in 10 minutes (at the most) from the comfort of your home computer while you are in your pyjamas. What I have found so far about ING DIRECT is that all procedures can be done with an extreme simplicity and from the comfort of your home.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
ING DIRECT calls its checking account: THRiVE Chequing Account. Why THRiVE? I guess because this THRiVE Chequing allows your money to thrive, to develop, to grow…&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Most checking accounts in Canadian banking institutions charge you a monthly fee. This is ridiculous if you ask me: banks are profiting from our own money, but that’s not enough for them: they still charge us a monthly fee for having our own money within their grasp, money from which they are profiting already.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
This is what THRiVE Chequing at ING DIRECT has to offer: &lt;/div&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;b&gt;NO MONTHLY FEES&lt;/b&gt;. Ask yourself if your current bank charges you a monthly fee and ask yourself if you should be paying for it?&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Unlimited transitions&lt;/b&gt;: once again, you can perform unlimited transitions at ING DIRECT for free.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Earn interest&lt;/b&gt; on the money you put on your THRiVE Chequing Account (yes, you heard well: this is a checking account that pays interest, just as saving accounts do).&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
I am not going to load you with more details…if you want to know more about the benefits of opening a THRiVE Chequing Account with ING DIRECT come here: &lt;a href="http://www.ingdirect.ca/en/chequing/" rel="nofollow" target="_blank"&gt;http://www.ingdirect.ca/en/chequing/&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Now, in order to open a THRiVE Chequing Account with ING DIRECT you have to do only TWO things:&lt;/div&gt;
&lt;ol style="text-align: justify;"&gt;
&lt;li&gt;&lt;a href="https://secure.ingdirect.ca/InitialINGDirect.html?command=goToCreateNewClientChequingCAD&amp;amp;locale=en_CA&amp;amp;device=web&amp;amp;sourceFlag=1321&amp;amp;mediaFlag=45&amp;amp;orangekey=40030923S1" rel="nofollow" target="_blank"&gt;Complete an online form&lt;/a&gt; that won’t take you more than 10 minutes. I am not exaggerating: this form won’t take you more than 10 minutes to fill. In order to fill the form click here: &lt;a href="https://secure.ingdirect.ca/InitialINGDirect.html?command=goToCreateNewClientChequingCAD&amp;amp;locale=en_CA&amp;amp;device=web&amp;amp;sourceFlag=1321&amp;amp;mediaFlag=45&amp;amp;orangekey=40030923S1" rel="nofollow" target="_blank"&gt;Open new THRiVE Chequing Account at ING DIRECT&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Write your initial deposit cheque (payable to yourself) for at least $100, and mail it to ING DIRECT, 111 Gordon Baker Road, Toronto, Ontario, M2H 3R1. Note: all new clients of ING DIRECT opening accounts for at least $100 box get a $50 bonus. What does this means? It means that you open your account with $100, but you are credited with $150; so ING DIRECT welcomes you with $50 box. &lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
That’s all: by completing the two steps above you will open a THRiVE Chequing Account at ING DIRECT, that will treat you with unlimited transactions, no monthly fees, fair saving interests and a $50 box welcome gift.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
If you have any questions, drop a line in the comments section below. I’ll do my best to answer.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
If you think this post might be useful to someone else, don’t hesitate in recommending by clicking the &lt;b&gt;&lt;span style="color: orange;"&gt;Google Plus (G+)&lt;/span&gt;&lt;/b&gt; button at the beginning of the post. Thanks!&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/2880743192040761968/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2013/04/How-to-open-THRiVE-checking-account-at-ING-DIRECT.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2880743192040761968?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2880743192040761968?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2013/04/How-to-open-THRiVE-checking-account-at-ING-DIRECT.html" title="How to open a checking account at ING DIRECT" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUIDR3czfSp7ImA9WhNbEU4.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-8200311418490848656</id><published>2013-01-13T20:21:00.003-05:00</published><updated>2013-01-13T22:19:36.985-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-13T22:19:36.985-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="FireMonkey" /><title>Enabling TLang to handle more than 17 translations: a workaround for a regression bug in Delphi XE3 </title><content type="html">I recently had to localize a &lt;b&gt;FireMonkey &lt;/b&gt;application and for that I aimed to use the &lt;a href="http://docwiki.embarcadero.com/Libraries/XE3/en/FMX.Types.TLang" rel="nofollow" target="_blank"&gt;TLang&lt;/a&gt; component. With &lt;b&gt;TLang &lt;/b&gt;you can define a collection of native strings to be localized and the corresponding translations to a particular language. To my surprise the component was allowing to store a maximum of 17 translations for the whole application. So, what about the other strings that need localization?&lt;br /&gt;
&lt;br /&gt;
It seems there’s a regression issue from &lt;b&gt;Delphi XE2&lt;/b&gt; to &lt;b&gt;Delphi XE3&lt;/b&gt; that is preventing &lt;span style="font-size: small;"&gt;&lt;b&gt;TLang &lt;/b&gt;&lt;/span&gt;to store more than 1&lt;b&gt;7&lt;/b&gt; translations. You can even find an entry for this in &lt;a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=109678" rel="nofollow" target="_blank"&gt;Embarcadero Quality Central&lt;/a&gt;, for which no workaround or fix has been provided up to this date.&lt;br /&gt;
&lt;br /&gt;
I found a programmatic workaround for this issue. Basically, the native strings and the translations could be loaded from text files in which each line will have the form:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NativeString1=Translation1&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeString2=Translation2&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeString3=Translation3&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;…………&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;NativeStringN=TranslationN&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You will need one file containing the native strings and the translations per language. These files can contain as many lines as you which (certainly more than 17). In order to load those files into an existing &lt;b&gt;TLang &lt;/b&gt;component you can use the function below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;procedure LoadTranslationsFromFile(aLangCode: string; aFileName: string; aLang: TLang);&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; Translations: TStrings;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; if (aLangCode &amp;lt;&amp;gt; '') and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (FileExists(aFileName)) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (Assigned(aLang)) then&lt;br /&gt;&amp;nbsp; begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Translations:= TStringList.Create;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Translations.LoadFromFile(aFileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aLang.Resources.AddObject(aLangCode, Translations);&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
For an example of how to use such function see below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; LoadTranslationsFromFile('ES', 'C:\Temp\Lang_Test_ES.txt', Lang1);&lt;br /&gt;&amp;nbsp; LoadTranslationsFromFile('EN', 'C:\Temp\Lang_Test_EN.txt', Lang1);&lt;br /&gt;end;&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
Hopefully this bug will be fixed in the near future; but meanwhile you can use this workaround to handle more than 17 translations with the &lt;b&gt;TLang &lt;/b&gt;component.&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display: none;"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/8200311418490848656/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2013/01/TLang-cannot-handle-more-than-17-translations-workaround-for-regression-issue-in-Delphi-XE3.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/8200311418490848656?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/8200311418490848656?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2013/01/TLang-cannot-handle-more-than-17-translations-workaround-for-regression-issue-in-Delphi-XE3.html" title="Enabling TLang to handle more than 17 translations: a workaround for a regression bug in Delphi XE3 " /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUICR3g4eSp7ImA9WhNbEU4.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-4944218353808619514</id><published>2012-12-17T10:47:00.002-05:00</published><updated>2013-01-13T22:19:26.631-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-13T22:19:26.631-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Test Driven Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Behavioral Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Template Method" /><category scheme="http://www.blogger.com/atom/ns#" term="DUnit" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Refactoring to patterns. Yet another TDD example coded in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
Long overdue here is my second article about Test Driven Development (TDD) in Delphi. This is a continuation of &lt;a href="http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html" target="_blank"&gt;TDD in Delphi: The Basics&lt;/a&gt;, another post that I wrote a few months earlier.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I would like to focus in a particular step within the TDD cycle: refactoring the code. Refactoring means optimizing, cleaning, shortening, beautifying, styling (put your own word here) the code without breaking the functionality; that is, without breaking your unit tests.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&amp;nbsp; &lt;br /&gt;
By having unit tests in place before refactoring, you guarantee that the changes to the code are safe. Refactoring can introduce bugs. To avoid those bugs you need your unit tests in place. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Refactoring can introduce something else: refactoring can introduce design patterns into your code. That means you don’t have to introduce the design patterns up-front, since your code can evolve from a “very rustic implementation” to a “pattern oriented implementation”. This is referred as “refactoring to patterns”. If you are interested on the topic, I advise you to read &lt;a href="http://www.amazon.com/gp/product/0321213351/ref=as_li_tf_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321213351&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20" rel="nofollow" target="_blank"&gt;Refactoring To Patterns by Joshua Kerievsky&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I’ll take the chess game as the base to my example. For simplicity, I’ll just refer to a couple of pieces: the knight and the bishop. In this example, I will just focus in refactoring some code with unit tests already in place. A detailed walk-through for the TDD cycle can be found in my &lt;a href="http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html" target="_blank"&gt;previous article&lt;/a&gt;, which is also based on the chess game.&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
The code is easy enough to be self-explanatory: basically, there is a class hierarchy in which &lt;b&gt;TPiece&lt;/b&gt; is the base class from which &lt;b&gt;TKnight &lt;/b&gt;and &lt;b&gt;TBishop &lt;/b&gt;derive. Take a quick look:&lt;/div&gt;
&lt;br /&gt;
&lt;code&gt;
unit ChessGame;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TPiece = class&lt;br /&gt;&amp;nbsp;private&lt;br /&gt;&amp;nbsp;&amp;nbsp; FX,&lt;br /&gt;&amp;nbsp;&amp;nbsp; FY: Byte;&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; constructor Create(aX, aY: Integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp; function IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TBishop = class (TPiece)&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TKnight = class(TPiece)&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TPiece }&lt;br /&gt;&lt;br /&gt;constructor TPiece.Create(aX, aY: Integer);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; inherited Create;&lt;br /&gt;&amp;nbsp; // TODO: check that this assignment is valid.&lt;br /&gt;&amp;nbsp; // Not now, ok? :-)&lt;br /&gt;&amp;nbsp; FX:= aX;&lt;br /&gt;&amp;nbsp; FY:= aY;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TKnight }&lt;br /&gt;&lt;br /&gt;function TKnight.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; x_diff,&lt;br /&gt;&amp;nbsp; y_diff: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; x_diff:= abs(aX - FX) ;&lt;br /&gt;&amp;nbsp; y_diff:= abs(aY - FY) ;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Result:= ((x_diff = 2) and (y_diff = 1))&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; or&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((y_diff = 2) and (x_diff = 1));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TKnight.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TBishop }&lt;br /&gt;&lt;br /&gt;function TBishop.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= abs(aX - FX) = abs(aY - FY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TBishop.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;b&gt;/////////////////////////////////////////////&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
unit TestChessGame;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;&amp;nbsp; TestFramework, ChessGame;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&amp;nbsp; // Test methods for class TPiece&lt;br /&gt;&amp;nbsp; TestTPiece = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FPiece: TPiece;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestIsWithinBoard;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; // Test methods for class TBishop&lt;br /&gt;&amp;nbsp; TestTBishop = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FBishop: TBishop;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestCanMoveTo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestisValidMove;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; // Test methods for class TKnight&lt;br /&gt;&amp;nbsp; TestTKnight = class(TTestCase)&lt;br /&gt;&amp;nbsp; strict private&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FKnight: TKnight;&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetUp; override;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TearDown; override;&lt;br /&gt;&amp;nbsp; published&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestCanMoveTo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure TestisValidMove;&lt;br /&gt;&amp;nbsp; end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FPiece := TPiece.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FPiece.Free;&lt;br /&gt;&amp;nbsp; FPiece := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTPiece.TestIsWithinBoard;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(4, 4));&lt;br /&gt;&lt;br /&gt;&amp;nbsp; //Tests boundaries&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(1, 1));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(1, 8));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(8, 1));&lt;br /&gt;&amp;nbsp; Check(FPiece.IsWithinBoard(8, 8));&lt;br /&gt;&lt;br /&gt;&amp;nbsp; //Test beyond the boundaries&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(3, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(3, -15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, 3));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(15, -15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, 3));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, 15));&lt;br /&gt;&amp;nbsp; CheckFalse(FPiece.IsWithinBoard(-15, -15));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FBishop := TBishop.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FBishop.Free;&lt;br /&gt;&amp;nbsp; FBishop := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TestCanMoveTo;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTBishop.TestisValidMove;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.SetUp;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FKnight := TKnight.Create(4, 4);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TearDown;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; FKnight.Free;&lt;br /&gt;&amp;nbsp; FKnight := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TestCanMoveTo;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TestTKnight.TestisValidMove;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; // Hey developer, indulge me here: believe&lt;br /&gt;&amp;nbsp; // that I fully wrote the code for this&lt;br /&gt;&amp;nbsp; // test already before writing anything else.&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;initialization&lt;br /&gt;&amp;nbsp; // Register any test cases with the test runner&lt;br /&gt;&amp;nbsp; RegisterTest(TestTPiece.Suite);&lt;br /&gt;&amp;nbsp; RegisterTest(TestTBishop.Suite);&lt;br /&gt;&amp;nbsp; RegisterTest(TestTKnight.Suite);&lt;br /&gt;end.&lt;/code&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Note that the method &lt;b&gt;CanMoveTo &lt;/b&gt;is duplicated in both &lt;b&gt;TKnight&amp;nbsp; &lt;/b&gt;and &lt;b&gt;TBishop&lt;/b&gt;; that’s not nice isn’t it? In order to fix this, we can pull-up the &lt;b&gt;CanMoveTo &lt;/b&gt;method to the &lt;b&gt;TPiece &lt;/b&gt;base class. Note this now: the &lt;b&gt;CanMoveTo &lt;/b&gt;has now become a “&lt;a href="http://www.yanniel.info/2011/06/template-method-design-pattern-delphi.html" target="_blank"&gt;template method&lt;/a&gt;”; because is a general algorithm applicable to all kind of chess pieces (&lt;b&gt;TKnight &lt;/b&gt;,&lt;b&gt;TBishop&lt;/b&gt;, etc) .&lt;br /&gt;
&lt;br /&gt;
This general algorithm has deferred some steps to be implemented in the subclasses; I mean, the &lt;b&gt;isValidMove &lt;/b&gt;method is still coded in the subclasses. Isn’t this a beauty?&amp;nbsp; You have now refactored your code and when doing so, you have introduced the Template Method Design Pattern.&lt;br /&gt;
&lt;br /&gt;
What’s even best, (don’t forget this because it is a key part): is that we can guarantee that our fancy refactoring didn’t break our pre-existing functionality. Why? Because we had unit tests in place written a long time ago. Writing unit test from the beginning gives a huge peace of mind to the developer :-) See the new refactored code below:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
unit ChessGameRefactored;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TPiece = class&lt;br /&gt;&amp;nbsp;private&lt;br /&gt;&amp;nbsp;&amp;nbsp; FX,&lt;br /&gt;&amp;nbsp;&amp;nbsp; FY: Byte;&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; constructor Create(aX, aY: Integer);&lt;br /&gt;&amp;nbsp;&amp;nbsp; function IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; virtual; abstract;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TBishop = class (TPiece)&lt;br /&gt;&amp;nbsp;public&lt;br /&gt;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; override;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;TKnight = class(TPiece)&lt;br /&gt;&amp;nbsp; public&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function isValidMove(aX, aY: Byte): Boolean; override;&lt;br /&gt;&amp;nbsp;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TPiece }&lt;br /&gt;&lt;br /&gt;constructor TPiece.Create(aX, aY: Integer);&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; inherited Create;&lt;br /&gt;&amp;nbsp; // TODO: check that this assignment is valid.&lt;br /&gt;&amp;nbsp; // Not now, ok? :-)&lt;br /&gt;&amp;nbsp; FX:= aX;&lt;br /&gt;&amp;nbsp; FY:= aY;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.IsWithinBoard(aX, aY: Integer): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPiece.CanMoveTo(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= IsWithinBoard(aX, aY) and&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsValidMove(aX, aY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TKnight }&lt;br /&gt;&lt;br /&gt;function TKnight.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;var&lt;br /&gt;&amp;nbsp; x_diff,&lt;br /&gt;&amp;nbsp; y_diff: Integer;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; x_diff:= abs(aX - FX) ;&lt;br /&gt;&amp;nbsp; y_diff:= abs(aY - FY) ;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Result:= ((x_diff = 2) and (y_diff = 1))&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; or&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((y_diff = 2) and (x_diff = 1));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TBishop }&lt;br /&gt;&lt;br /&gt;function TBishop.isValidMove(aX, aY: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;&amp;nbsp; Result:= abs(aX - FX) = abs(aY - FY);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Conclusion, in addition to all the cool things of TDD there’s the possibility of refining your design not up-front, but when refactoring your code. Design patterns can be introduced at any time and we know that such introduction, if late, is not going to break our logic, because we have unit tests in place to prevent that from happening.&lt;br /&gt;
&lt;br /&gt;
Some related reading below:&lt;/div&gt;
&lt;a href="http://www.amazon.com/gp/product/0321213351/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321213351&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0321213351&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321213351" style="border: none !important; margin: 0px !important;" width="1" /&gt;

&lt;a href="http://www.amazon.com/gp/product/0321146530/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321146530&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0321146530&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321146530" style="border: none !important; margin: 0px !important;" width="1" /&gt;

&lt;a href="http://www.amazon.com/gp/product/0201633612/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0201633612&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0201633612&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201633612" style="border: none !important; margin: 0px !important;" width="1" /&gt;

&lt;a href="http://www.amazon.com/gp/product/0596007124/ref=as_li_tf_il?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596007124&amp;amp;linkCode=as2&amp;amp;tag=lmaoookaiie-20"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0596007124&amp;amp;Format=_SL160_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0596007124" style="border: none !important; margin: 0px !important;" width="1" /&gt;

&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display: none;"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/4944218353808619514/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/12/refactoring-to-patterns-in-delphi.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4944218353808619514?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4944218353808619514?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/12/refactoring-to-patterns-in-delphi.html" title="Refactoring to patterns. Yet another TDD example coded in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DkUFRH0zcSp7ImA9WhJaE0w.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-3135301535028571716</id><published>2012-10-03T20:36:00.002-04:00</published><updated>2012-10-03T21:30:15.389-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-03T21:30:15.389-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Cuba" /><category scheme="http://www.blogger.com/atom/ns#" term="services" /><category scheme="http://www.blogger.com/atom/ns#" term="Cubacel" /><category scheme="http://www.blogger.com/atom/ns#" term="ETECSA" /><category scheme="http://www.blogger.com/atom/ns#" term="phone" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet" /><category scheme="http://www.blogger.com/atom/ns#" term="cell" /><title>What types of mobile phones are used in Cuba?</title><content type="html">&lt;div style="text-align: justify;"&gt;
All mobile phones in Cuba are linked together by a GSM cellular network, operating in the 900MHz band throughout the island. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
The 850MHz band is also operational in selected locations, namely: Havana City, Varadero, Cayo Coco and Cayo Guillermo.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
If you were to buy a cell phone for a person living in Cuba: I would recommend acquiring an &lt;b&gt;unlocked quad-band phone (GPRS compatible)&lt;/b&gt;. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
It is important for the cellular phone to be &lt;b&gt;unlocked&lt;/b&gt;; otherwise it won’t work with the Cuban mobile operator: Cubacell. Of course, a locked phone could be unlocked, but why to bother? You can buy a brand new unlocked phone and you will save the money and the time for unlocking it after.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;b&gt;Quad -band&lt;/b&gt; phones operate in the four major GSM bands: 850, 900, 1800 y 1900 MHz. With this kind of phone you will be able to get mobile coverage in the whole island. Technically speaking you don’t need the 1800 and 1900 MHz bands in Cuba, but it does not hurt to have them as well. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
One final tip: the MMS service is available in Cuba. Most people don’t know this. This service allows you to send multimedia messages containing text, images, audio y video to a Cuban cell phone. Now, in order to use this service, your cell should support &lt;i&gt;GPRS &lt;/i&gt;technology. Note that not all GSM mobile phones support GPRS technology. It depends on the model, brand and year of production.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
The MMS service is not activated by default. In order to use it, you should activate the service following &lt;a href="http://www.etecsa.cu/?page=telefonia_movil&amp;amp;sub=cubacel_envio_sms_mms#MMS" rel="nofollow" target="_blank"&gt;these steps&lt;/a&gt; (in Spanish).&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I have listed below a selection of phones that you can buy trough Amazon. All these phones are unlocked, quad –band (GSM) and GPRS compatible. These phones will work in Cuba. Amazon is a trustable online retailer, probably the largest and better known in the world. So buying through Amazon is safe and painless.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Motorola &lt;/b&gt; &lt;a category="cell phones &amp;amp; accessories" href="http://www.blogger.com/blogger.g?blogID=3701737190756431503" search="Motorola unlocked quad-band phone GPRS" type="amzn"&gt;(More cells from Motorola...)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B001D7AVCG&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B000SZTRVK&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B0016JDE34&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sony Ericsson &lt;/b&gt; &lt;a category="cell phones &amp;amp; accessories" href="http://www.blogger.com/blogger.g?blogID=3701737190756431503" search="Sony Ericsson unlocked quad-band phone GPRS" type="amzn"&gt;(More cells from Sony Ericsson...)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B001BKK4EU&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B001CCKDZW&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B005DIPSX8&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Nokia&lt;/b&gt; &lt;a category="cell phones &amp;amp; accessories" href="http://www.blogger.com/blogger.g?blogID=3701737190756431503" search="Nokia unlocked quad-band phone GPRS" type="amzn"&gt;More cells from Nokia...&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B000YLLB4E&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B006HYA71K&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;

&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=lmaoookaiie-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B001VJ20ZW&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;If you cannot find the cell phone you are looking for in the list above, then you might try the search box just below:&lt;/b&gt;&amp;nbsp;
&lt;br /&gt;
&lt;br /&gt;
&lt;script charset="utf-8" src="http://ws.amazon.com/widgets/q?rt=tf_sw&amp;amp;ServiceVersion=20070822&amp;amp;MarketPlace=US&amp;amp;ID=V20070822/US/lmaoookaiie-20/8002/90b01d1d-ae67-4d2b-8356-13692e07ab32" type="text/javascript"&gt; &lt;/script&gt; &lt;noscript&gt;&lt;a HREF="http://ws.amazon.com/widgets/q?rt=tf_sw&amp;ServiceVersion=20070822&amp;MarketPlace=US&amp;ID=V20070822%2FUS%2Flmaoookaiie-20%2F8002%2F90b01d1d-ae67-4d2b-8356-13692e07ab32&amp;Operation=NoScript"&gt;Amazon.com Widgets&lt;/A&gt;&lt;/noscript&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Since you are reading this article you might be interested in knowing &lt;a href="http://www.yanniel.info/2010/10/recharge-cell-phone-cuba-internet.html" target="_blank"&gt;how to recharge the cell phone of a person living in Cuba over the internet&lt;/a&gt;. Check it out!&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/3135301535028571716/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/10/what-kind-of-cell-phones-operate-in-cuba.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3135301535028571716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3135301535028571716?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/10/what-kind-of-cell-phones-operate-in-cuba.html" title="What types of mobile phones are used in Cuba?" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UNRXw8eSp7ImA9WhJbFk8.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-2657261444744275602</id><published>2012-09-23T23:32:00.003-04:00</published><updated>2012-09-25T23:14:54.271-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-25T23:14:54.271-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Brick Platinum Card" /><category scheme="http://www.blogger.com/atom/ns#" term="EasyWeb" /><category scheme="http://www.blogger.com/atom/ns#" term="TD" /><category scheme="http://www.blogger.com/atom/ns#" term="TD Canada Trust" /><category scheme="http://www.blogger.com/atom/ns#" term="The Brick" /><category scheme="http://www.blogger.com/atom/ns#" term="Online Banking" /><title>Make payments to your Brick Platinum Card from TD EasyWeb</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
You can use TD EasyWeb, the online banking system of TD Canada Trust, in order to make payments or contributions to your Brick Platinum card. For that, you need to add your Brick Platinum Card as a new payee in your EasyWeb account.&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
A Brick Platinum Card looks like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s1600/Brick-Platinum-Card-+The-Brick.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s1600/Brick-Platinum-Card-+The-Brick.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Brick Platinum Card - The Brick&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
Follow the steps below in order to make online contributions to your Brick Platinum Card from TD EasyWeb:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Login to TD Easy Web and you will land in the &lt;span style="color: #38761d;"&gt;&lt;b&gt;View Accounts&lt;/b&gt;&lt;/span&gt; page.&lt;/li&gt;
&lt;li&gt;Find and click the &lt;b&gt;&lt;u&gt;&lt;span style="color: #38761d;"&gt;Payments &amp;amp; Transfers&lt;/span&gt;&lt;/u&gt;&lt;/b&gt; link. You will see now the &lt;b&gt;&lt;span style="color: #38761d;"&gt;Payments and Transfers&lt;/span&gt;&lt;/b&gt; page.&lt;/li&gt;
&lt;li&gt;Find and click the &lt;b&gt;&lt;span style="background-color: #38761d;"&gt;&lt;span style="color: white;"&gt;Add a New Payee&lt;/span&gt;&lt;/span&gt;&lt;/b&gt; button.&amp;nbsp; In the new page, type in &lt;b&gt;HSBC RETAIL SERVICES&lt;/b&gt; in the &lt;b&gt;Enter Payee Name&lt;/b&gt; text box and click the &lt;span style="color: white;"&gt;&lt;b&gt;&lt;span style="background-color: #38761d;"&gt;Search&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; button. &lt;/li&gt;
&lt;li&gt;In the new page, write down your Brick Platinum Card number within the &lt;b&gt;Payee Account&lt;/b&gt; text box. When doing so, add a leading zero to the 15 digit card number.&amp;nbsp;&amp;nbsp; For example, if your Brick Card number is 0000 1234 5678 999, then you should type 0000 0123 4567 8999. After this click, the &lt;span style="color: white;"&gt;&lt;b&gt;&lt;span style="background-color: #b45f06;"&gt;Next&amp;gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; button.&lt;/li&gt;
&lt;li&gt;In the next page click the &lt;span style="color: white;"&gt;&lt;span style="background-color: #b45f06;"&gt;&lt;b&gt;Finish&lt;/b&gt;&lt;/span&gt;&lt;/span&gt; button.&lt;/li&gt;
&lt;li&gt;Now you can click the &lt;span style="color: white;"&gt;&lt;b&gt;&lt;span style="background-color: #b45f06;"&gt;Pay this Payee&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; button in order to make a contribution to the Brick Platinum card right away. &lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: center;"&gt;
&lt;b&gt;&lt;span style="color: red;"&gt;The online payment should be sent 7 days prior to the payment due date to make sure it arrives in time for processing.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
This is all for this tutorial. You could also accomplish the same from within the RBC online banking. For details take a look at: &lt;a href="http://www.yanniel.info/2012/08/online-payments-brick-card-rbc.html"&gt;Make payments to your Brick Platinum Card from the RBC Online Banking&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
If you think this info is useful, then share it with your fiends in Google Plus (G+). For that just click the &lt;span style="color: orange;"&gt;&lt;b&gt;Google Plus (G+)&lt;/b&gt;&lt;/span&gt; button close to the title of this post.&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/2657261444744275602/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/09/online-payments-brick-card-td-easyweb.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2657261444744275602?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2657261444744275602?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/09/online-payments-brick-card-td-easyweb.html" title="Make payments to your Brick Platinum Card from TD EasyWeb" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s72-c/Brick-Platinum-Card-+The-Brick.jpg" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DUYBRnk4fip7ImA9WhJbFUk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-2373905208865164514</id><published>2012-09-05T21:46:00.000-04:00</published><updated>2012-09-25T00:25:57.736-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-25T00:25:57.736-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Brick Platinum Card" /><category scheme="http://www.blogger.com/atom/ns#" term="The Brick" /><category scheme="http://www.blogger.com/atom/ns#" term="Online Banking" /><title>Check your Brick Platinum Card balance online</title><content type="html">&lt;div style="text-align: justify;"&gt;
If you want to check your Brick Platinum Card balance over the Internet, the first thing you need to do is to register with the HSBC Online Customer Care.&amp;nbsp; For that just click here: &lt;a href="https://www.service.hsbcretailservices.ca/ecare/enrollmentform?&amp;amp;locale=en_CA&amp;amp;brand=HS_000_000" rel="nofollow" target="_blank"&gt;Enrollment form&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
You will be redirected to a registration form in which you will have to type in some information like:&amp;nbsp;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Account Number&lt;/b&gt;: The Brick Card number preceded with a zero to the left. For instance, if your Brick Card number is 0000 1234 5678 999, then you should type 0000 0123 4567 8999.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Date of Birth&lt;/b&gt;: The Brick Platinum cardholder’s date of birth.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Postal Code&lt;/b&gt;: The Brick Platinum cardholder’s postal code&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Loing ID&lt;/b&gt; and &lt;b&gt;Password&lt;/b&gt;: A login and password for accessing the Online Customer Care.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Two security questions&lt;/b&gt;: Just in case you forget your credentials in the future (login ID and password)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Email Address&lt;/b&gt;: The Brick Platinum cardholder’s email address. &lt;/li&gt;
&lt;li&gt;&lt;b&gt;Statement Delivery Preference&lt;/b&gt;: Whether you prefer to receive paper statements over regular mail or electronic statements over email. I particularly prefer the electronic statements.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Email Alerts&lt;/b&gt;: Check this out if you want to receive email alerts when a payment has been received, when your payment is past due and when a new statement becomes available.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
Finally, just click the &lt;b&gt;Submit &lt;/b&gt;button at the end of the form. With that you'll have completed the registration process. Shortly after, you will receive an email from HSBC Retail Services welcoming you to the Online Customer Care.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
If you want to check your Brick Platinum Card balance just login with your &lt;b&gt;Login ID&lt;/b&gt; and &lt;b&gt;Password&lt;/b&gt; in the &lt;a href="https://www.service.hsbcretailservices.ca/ecare/loginform?&amp;amp;locale=en_CA&amp;amp;brand=HS_000_000" rel="nofollow" target="_blank"&gt;Online Customer Care&lt;/a&gt; web portal.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Important: you cannot make online payments from within the Online Customer Care portal. You can only review your statements and balance. If you want to make online contributions to your Brick Platinum Card refer to the following articles: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.yanniel.info/2012/08/online-payments-brick-card-rbc.html"&gt;Make payments to your Brick Platinum Card from the RBC Online Banking&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.yanniel.info/2012/09/online-payments-brick-card-td-easyweb.html"&gt;Make payments to your Brick Platinum Card from TD EasyWeb&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/2373905208865164514/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/09/check-brick-platinum-card-balance-online.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2373905208865164514?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/2373905208865164514?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/09/check-brick-platinum-card-balance-online.html" title="Check your Brick Platinum Card balance online" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0QHRHYycCp7ImA9WhJbFk8.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-3141347634429809320</id><published>2012-08-27T23:53:00.001-04:00</published><updated>2012-09-25T23:15:35.898-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-25T23:15:35.898-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Brick Platinum Card" /><category scheme="http://www.blogger.com/atom/ns#" term="RBC" /><category scheme="http://www.blogger.com/atom/ns#" term="Royal Bank of Canada" /><category scheme="http://www.blogger.com/atom/ns#" term="Royal Bank" /><category scheme="http://www.blogger.com/atom/ns#" term="The Brick" /><category scheme="http://www.blogger.com/atom/ns#" term="Online Banking" /><title>Make payments to your Brick Platinum Card from the RBC Online Banking</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
If you financed some new furniture at The Brick by getting a Brick Platinum Card, then you can arrange your payments thought the RBC online banking.&amp;nbsp; I prefer to do the contributions from the comfort of my home as opposed to physically paying at the store.&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Your Brick Platinum Card should look like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s1600/Brick-Platinum-Card-+The-Brick.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s1600/Brick-Platinum-Card-+The-Brick.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;o:OfficeDocumentSettings&gt;
  &lt;o:AllowPNG/&gt;
 &lt;/o:OfficeDocumentSettings&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:WordDocument&gt;
  &lt;w:View&gt;Normal&lt;/w:View&gt;
  &lt;w:Zoom&gt;0&lt;/w:Zoom&gt;
  &lt;w:TrackMoves/&gt;
  &lt;w:TrackFormatting/&gt;
  &lt;w:PunctuationKerning/&gt;
  &lt;w:ValidateAgainstSchemas/&gt;
  &lt;w:SaveIfXMLInvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;
  &lt;w:IgnoreMixedContent&gt;false&lt;/w:IgnoreMixedContent&gt;
  &lt;w:AlwaysShowPlaceholderText&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;
  &lt;w:DoNotPromoteQF/&gt;
  &lt;w:LidThemeOther&gt;EN-CA&lt;/w:LidThemeOther&gt;
  &lt;w:LidThemeAsian&gt;X-NONE&lt;/w:LidThemeAsian&gt;
  &lt;w:LidThemeComplexScript&gt;X-NONE&lt;/w:LidThemeComplexScript&gt;
  &lt;w:Compatibility&gt;
   &lt;w:BreakWrappedTables/&gt;
   &lt;w:SnapToGridInCell/&gt;
   &lt;w:WrapTextWithPunct/&gt;
   &lt;w:UseAsianBreakRules/&gt;
   &lt;w:DontGrowAutofit/&gt;
   &lt;w:SplitPgBreakAndParaMark/&gt;
   &lt;w:EnableOpenTypeKerning/&gt;
   &lt;w:DontFlipMirrorIndents/&gt;
   &lt;w:OverrideTableStyleHps/&gt;
  &lt;/w:Compatibility&gt;
  &lt;m:mathPr&gt;
   &lt;m:mathFont m:val="Cambria Math"/&gt;
   &lt;m:brkBin m:val="before"/&gt;
   &lt;m:brkBinSub m:val="&amp;#45;-"/&gt;
   &lt;m:smallFrac m:val="off"/&gt;
   &lt;m:dispDef/&gt;
   &lt;m:lMargin m:val="0"/&gt;
   &lt;m:rMargin m:val="0"/&gt;
   &lt;m:defJc m:val="centerGroup"/&gt;
   &lt;m:wrapIndent m:val="1440"/&gt;
   &lt;m:intLim m:val="subSup"/&gt;
   &lt;m:naryLim m:val="undOvr"/&gt;
  &lt;/m:mathPr&gt;&lt;/w:WordDocument&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
  DefSemiHidden="true" DefQFormat="false" DefPriority="99"
  LatentStyleCount="267"&gt;
  &lt;w:LsdException Locked="false" Priority="0" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Normal"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="heading 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/&gt;
  &lt;w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 7"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 8"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" Name="toc 9"/&gt;
  &lt;w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/&gt;
  &lt;w:LsdException Locked="false" Priority="10" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Title"/&gt;
  &lt;w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/&gt;
  &lt;w:LsdException Locked="false" Priority="11" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/&gt;
  &lt;w:LsdException Locked="false" Priority="22" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Strong"/&gt;
  &lt;w:LsdException Locked="false" Priority="20" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/&gt;
  &lt;w:LsdException Locked="false" Priority="59" SemiHidden="false"
   UnhideWhenUsed="false" Name="Table Grid"/&gt;
  &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/&gt;
  &lt;w:LsdException Locked="false" Priority="1" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/&gt;
  &lt;w:LsdException Locked="false" Priority="34" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/&gt;
  &lt;w:LsdException Locked="false" Priority="29" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Quote"/&gt;
  &lt;w:LsdException Locked="false" Priority="30" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/&gt;
  &lt;w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/&gt;
  &lt;w:LsdException Locked="false" Priority="19" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/&gt;
  &lt;w:LsdException Locked="false" Priority="21" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/&gt;
  &lt;w:LsdException Locked="false" Priority="31" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/&gt;
  &lt;w:LsdException Locked="false" Priority="32" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/&gt;
  &lt;w:LsdException Locked="false" Priority="33" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Book Title"/&gt;
  &lt;w:LsdException Locked="false" Priority="37" Name="Bibliography"/&gt;
  &lt;w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/&gt;
 &lt;/w:LatentStyles&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 10]&gt;
&lt;style&gt;
 /* Style Definitions */
 table.MsoNormalTable
 {mso-style-name:"Table Normal";
 mso-tstyle-rowband-size:0;
 mso-tstyle-colband-size:0;
 mso-style-noshow:yes;
 mso-style-priority:99;
 mso-style-parent:"";
 mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
 mso-para-margin-top:0cm;
 mso-para-margin-right:0cm;
 mso-para-margin-bottom:10.0pt;
 mso-para-margin-left:0cm;
 line-height:115%;
 mso-pagination:widow-orphan;
 font-size:11.0pt;
 font-family:"Calibri","sans-serif";
 mso-ascii-font-family:Calibri;
 mso-ascii-theme-font:minor-latin;
 mso-hansi-font-family:Calibri;
 mso-hansi-theme-font:minor-latin;
 mso-bidi-font-family:"Times New Roman";
 mso-bidi-theme-font:minor-bidi;
 mso-fareast-language:EN-US;}
&lt;/style&gt;
&lt;![endif]--&gt;Brick Platinum Card - The Brick&lt;span style="font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11.0pt; line-height: 115%; mso-ansi-language: EN-CA; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
This is a comprehensive step by step guideline that will allow you to contribute to your Brick Platinum Card balance from the RBC Online Baking:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Sign-in to RBC online baking. Once you sign-in, you’ll see the &lt;b&gt;&lt;span style="color: blue;"&gt;Accounts Summary&lt;/span&gt;&lt;/b&gt; page. &lt;/li&gt;
&lt;li&gt;Find and click the &lt;b&gt;&lt;u style="color: blue;"&gt;Pay Bills &amp;amp; Transfer Funds&lt;/u&gt;&lt;/b&gt; link. You will be redirected to the &lt;b style="color: blue;"&gt;Pay Bills &amp;amp; Transfer Funds&lt;/b&gt; page.&lt;/li&gt;
&lt;li&gt;Find and click the &lt;b&gt;&lt;u&gt;&lt;span style="color: blue;"&gt;Add Payee&lt;/span&gt;&lt;/u&gt;&lt;/b&gt; link. You will be redirected to the &lt;b style="color: blue;"&gt;Add Payee&lt;/b&gt; page.&lt;/li&gt;
&lt;li&gt;In the &lt;b&gt;Payee name&lt;/b&gt; text box type &lt;b&gt;HSBC RETAIL SERVICES&lt;/b&gt; and click the &lt;b style="background-color: blue; color: white;"&gt;Search&lt;/b&gt; button. You will be redirected to a page containing a list of possible payee matches.&amp;nbsp; Select the radio button labeled &lt;b&gt;HSBC RETAIL SERVICES&lt;/b&gt; and click the &lt;b&gt;&lt;span style="background-color: blue; color: white;"&gt;Continue&lt;/span&gt;&lt;/b&gt; button. You will be redirected to the &lt;b&gt;&lt;span style="color: blue;"&gt;Payee Information&lt;/span&gt;&lt;/b&gt; page. &lt;/li&gt;
&lt;li&gt;Type in your Brick Platinum Card number in the edit box. When doing so, add a leading zero to the 15 digit card number.&amp;nbsp;&amp;nbsp; For example, if your Brick Card number is 0000 1234 5678 999, then you should type 0000 0123 4567 8999. Once you do this, click the &lt;b&gt;&lt;span style="background-color: blue; color: white;"&gt;Continue&lt;/span&gt;&lt;/b&gt; button. You will be redirected to the &lt;b style="color: blue;"&gt;Add Payee Confirmation&lt;/b&gt; page.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Click the &lt;b&gt;&lt;span style="background-color: blue; color: white;"&gt;Confirm&lt;/span&gt;&lt;/b&gt; button. You will be redirected to the &lt;b style="color: blue;"&gt;Add Payee Completed&lt;/b&gt; page. At this point you have successfully added your Brick Platinum Card to your list of payees.&lt;/li&gt;
&lt;li&gt;To make a payment go to the &lt;b style="color: blue;"&gt;Accounts Summary&lt;/b&gt; page and use the &lt;b&gt;&lt;span style="color: blue;"&gt;Quick Payments &amp;amp; Transfers&lt;/span&gt;&lt;/b&gt; dialog. It’s as easy as specifying the source from which you want to take your funds (checking account, saving account, etc.), selecting Brick Platinum HSBC as the receiver of the payment and entering the amount of money that you would like to transfer.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: center;"&gt;
&lt;b&gt;&lt;span style="color: red;"&gt;The online transfer should be done 7 days in advance to the payment due date to guarantee it comes in time for processing.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
If you bank with TD Canada Trust you might want to check this out: &lt;a href="http://www.yanniel.info/2012/09/online-payments-brick-card-td-easyweb.html"&gt;Make payments to your Brick Platinum Card from TD EasyWeb&lt;/a&gt;. &lt;br /&gt;
&lt;ol&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
That’s all folks :-) If you find this tutorial helpful, would you mind sharing it by clicking the &lt;b&gt;&lt;span style="color: orange;"&gt;Google Plus (G+)&lt;/span&gt;&lt;/b&gt; button at the beginning of this post? Thanks! &lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/3141347634429809320/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/08/online-payments-brick-card-rbc.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3141347634429809320?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3141347634429809320?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/08/online-payments-brick-card-rbc.html" title="Make payments to your Brick Platinum Card from the RBC Online Banking" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-J-XTbQaU7YQ/UDw-OeXoU9I/AAAAAAAAAKM/jLOrdYS8qjM/s72-c/Brick-Platinum-Card-+The-Brick.jpg" height="72" width="72" /><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CkYBRnc5fSp7ImA9WhNWF0s.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-7726759895638025532</id><published>2012-03-08T11:12:00.020-05:00</published><updated>2012-12-17T11:02:37.925-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-17T11:02:37.925-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Test Driven Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="DUnit" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Test Driven Development in Delphi: The Basics</title><content type="html">&lt;div style="text-align: justify;"&gt;
I intend to write a &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" rel="nofollow" target="_blank"&gt;Test Driven Development (TDD)&lt;/a&gt; series, targeted for Delphi developers. I will use &lt;a href="http://dunit.sourceforge.net/" rel="nofollow" target="_blank"&gt;DUnit&lt;/a&gt;, the &lt;b&gt;unit testing&lt;/b&gt; framework for Delphi.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Note folks that the purpose of this is NOT to discuss the Pros and Cons of &lt;b&gt;TDD&lt;/b&gt;, &lt;b&gt;Unit Testing&lt;/b&gt; or whatsoever. The purpose is just to give a few examples. I would love if you help me when the complexity starts climbing.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
If needed, for a quick understanding of what &lt;b&gt;TDD &lt;/b&gt;or &lt;b&gt;Unit Testing&lt;/b&gt; is, refer to the links above, or &lt;i&gt;check&lt;/i&gt; out the &lt;a href="http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html#TDD-Kent-Beck" title="Test Driven Development: By Example (Kent Beck)"&gt;book&lt;/a&gt; at the end of the article.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
In &lt;b&gt;TDD &lt;/b&gt;you don’t write the application code first, instead you write the test cases first. The &lt;b&gt;TDD&lt;/b&gt; cycle is as follows:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;At the beginning you just write one test, and later on, more tests can be added.&lt;/li&gt;
&lt;li&gt;Make sure the initial test fails; this will validate the test harness.  &lt;/li&gt;
&lt;li&gt;Write some code to pass the test. Important: don’t over-code. Just add the code needed to pass the test and period. The code does not have to be elegant at this point.&lt;/li&gt;
&lt;li&gt;Run the test: if it fails, then you have to go back to step 3 and fix your code in order to pass the test. When you succeed, then move on to step 5.&lt;/li&gt;
&lt;li&gt;Improve and optimize your code: make it elegant, more efficient, avoid duplications, etc, etc. This is called code refactoring.&lt;/li&gt;
&lt;li&gt;When refactoring your code, maybe, by accident, you break the functionality. How can you be sure that everything is working as it should? Just re-run your test and it will tell you if the previous refactoring introduced a failure or not.&lt;/li&gt;
&lt;li&gt;Go to step 1 and add a new test if needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
The example: let’s consider the chess game. The goal will be to implement the code to verify whether a piece is placed in a valid position within the board. We are only going to implement one test: &lt;i&gt;SetPositionTest&lt;/i&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I will number the columns (X coordinate) from 1 to 8 starting at the bottom left-hand corner. In the same way, I will number the rows (Y coordinate) from 1 to 8 starting at the bottom left-hand corner. &lt;/div&gt;
&lt;br /&gt;
8&lt;br /&gt;
7&lt;br /&gt;
6&lt;br /&gt;
5&lt;br /&gt;
4&lt;br /&gt;
3&lt;br /&gt;
2&lt;br /&gt;
1  2 3 4 5 6 7 8 &lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
For a step by step tutorial of how to use, configure and setup &lt;b&gt;DUnit &lt;/b&gt;you can read the &lt;a href="http://dunit.sourceforge.net/README.html" rel="nofollow" target="_blank"&gt;English&lt;/a&gt; or &lt;a href="http://dunit.sourceforge.net/README_CHT.html" rel="nofollow" target="_blank"&gt;Chinese&lt;/a&gt; versions of the tutorial.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Initially, the testing code should look like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit ChessPiecesTests;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp;&amp;nbsp; TestFrameWork;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TPieceTest = class(TTestCase)&lt;br /&gt;
&amp;nbsp; published&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure SetPositionTest;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; ChessPieces;&lt;br /&gt;
&lt;br /&gt;
{ TPieceTest }&lt;br /&gt;
&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
begin&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
initialization&lt;br /&gt;
&amp;nbsp; TestFramework.RegisterTest(TPieceTest.Suite);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
If you run that test, it will succeed since no &lt;i&gt;checks &lt;/i&gt;are being performed within the &lt;i&gt;SetPositionTest&lt;/i&gt; procedure. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Each test is composed by one or more &lt;i&gt;checks&lt;/i&gt;. I suggest adding the &lt;i&gt;checks &lt;/i&gt;little by little. Every time you add a &lt;i&gt;check&lt;/i&gt;, you should add business code to pass the corresponding test.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Now, let’s make the test fail on purpose. For that, let’s add one &lt;i&gt;check &lt;/i&gt;to the SetPositionTest procedure. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Check(True = False,  '');&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b&gt;True &lt;/b&gt;is never &lt;b&gt;False&lt;/b&gt;. So, this test will fail. If it doesn’t fail, then something is wrong with you test harness. Fix it. You can remove this initial &lt;i&gt;check &lt;/i&gt;once you run the test and it fails.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Now, let’s add a real &lt;i&gt;check &lt;/i&gt;to our test. Something like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Piece: TPiece;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Piece:= TPiece.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(4, 4) = True,  '');&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Piece.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
If you run this test, you will get a compilation error! Yes, that’s right. You don’t have business code yet. You just have the test. This is what &lt;b&gt;TDD &lt;/b&gt;is all about: test first, business code later. Get the point?&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
To avoid the compilation error, we will code a separate unit (&lt;i&gt;ChessPieces&lt;/i&gt;) and we will add it to the &lt;i&gt;uses &lt;/i&gt;clause of our &lt;i&gt;ChessPiecesTests &lt;/i&gt;unit. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit ChessPieces;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TPiece = class&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TPiece }&lt;br /&gt;
&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Run the test again and now the compilation error is gone. Nonetheless, the test fails, because the &lt;i&gt;Piece.SetPosition(4, 4)&lt;/i&gt; evaluates to &lt;b&gt;False&lt;/b&gt;. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Let’s add the minimum business code possible to pass this test:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= True;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
This passes the test. What? Yes, this passes the test, right? &lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
OK, what now? Well, we keep adding new &lt;i&gt;checks &lt;/i&gt;to the test and every time this happens, we need to add new business code in order to pass it. It is very important to add &lt;i&gt;checks &lt;/i&gt;to test the boundaries of whatever we are trying to code. I think you are getting the point, so I will just add a bunch of &lt;i&gt;checks &lt;/i&gt;at once:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TPieceTest.SetPositionTest;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Piece: TPiece;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Piece:= TPiece.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test trivial (normal) workflow&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(4, 4) = True,  '');&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Tests boundaries&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(1, 1) = True,  '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(1, 8) = True,  '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(8, 1) = True,  '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(8, 8) = True,  '');&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Test beyond the boundaries&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(3,    15) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(3,   -15) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,    3) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,   15) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(15,  -15) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15,   3) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15,  15) = False, '');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Check(Piece.SetPosition(-15, -15) = False, '');&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp; &amp;nbsp; Piece.Free;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
The test above is even &lt;i&gt;checking &lt;/i&gt;for the attempts of positioning a piece outside the chess board.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
To pass that test let’s write some business code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= True;&lt;br /&gt;
&amp;nbsp; if (aY &amp;lt; 1) or (aY &amp;gt; 8) then Result:= False&lt;br /&gt;
&amp;nbsp; else if (aX &amp;lt; 1) or (aX &amp;gt; 8) then Result:= False;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Run the test and see how it passes. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The code above could be refactored or even rewritten. The tests will remain the same, allowing us to catch any bugs introduced with the code change.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
For instance, we could write the procedure above as follows:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
function TPiece.SetPosition(aX, aY: Integer): Boolean;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= (aX &amp;gt; 0) and&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aX &amp;lt; 9) and&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;gt; 0) and&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (aY &amp;lt; 9);&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Run the test, and it will tell you if this refactoring (or reimplementation) works ok. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
It’s important to note that a good test should cover all possible scenarios and workflows. Pay special attention to the boundaries. At this point, a good understanding of the requisites is indispensable. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Finally, more and more tests will be needed in a real world application. Each test will have its own &lt;i&gt;checks&lt;/i&gt;. Each test will cover one piece of the functionality: this is what &lt;b&gt;unit testing&lt;/b&gt; is intended for.&lt;br /&gt;
&lt;br /&gt;
For further reading I recommend you &lt;b&gt;Test Driven Development: By Example&lt;/b&gt; by &lt;i&gt;Kent Beck&lt;/i&gt;. Check it out just below:&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://www.blogger.com/post-edit.g?blogID=3701737190756431503&amp;amp;postID=7726759895638025532" name="TDD-Kent-Beck"&gt;&lt;/a&gt;&lt;a href="http://www.amazon.com/gp/product/0321146530/ref=as_li_tf_il?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321146530" rel="nofollow" target="_blank"&gt;&lt;img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;amp;Format=_SL160_&amp;amp;ASIN=0321146530&amp;amp;MarketPlace=US&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;tag=lmaoookaiie-20&amp;amp;ServiceVersion=20070822" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321146530" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display: none;"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/7726759895638025532/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7726759895638025532?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7726759895638025532?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/03/tdd-in-delphi-dunit-framework.html" title="Test Driven Development in Delphi: The Basics" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>6</thr:total></entry><entry gd:etag="W/&quot;DUEFSXo_cSp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-1098229902213601340</id><published>2012-02-03T14:26:00.014-05:00</published><updated>2012-12-13T20:13:38.449-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:13:38.449-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Deep copying (cloning) objects in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
When I first took a look at the prototype design pattern in &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" rel="nofollow" target="_blank"&gt;GoF&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;(years ago), I realized that there was a big obstacle (challenge) to implement it in Delphi: How to write a routine to really clone (not just recreate) an object? In other words, how to perform a &lt;a href="http://en.wikipedia.org/wiki/Object_copy#Deep_copy" rel="nofollow" target="_blank"&gt;deep-copy&lt;/a&gt; of a living object in Delphi.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
There are approaches out there mimicking the &lt;b&gt;deep copy&lt;/b&gt; by simply calling the constructor and reassigning the state of the object by hand (I don’t like it). There are others exposing that a &lt;b&gt;deep copy&lt;/b&gt; could be accomplished for the descendants of &lt;i&gt;TPersistent &lt;/i&gt;by calling the &lt;i&gt;Assign &lt;/i&gt;method (I don’t like it either). &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
With the new RTTI extensions it seemed to me (and to others) that a &lt;b&gt;deep copy&lt;/b&gt; could be accomplished using &lt;a href="http://en.wikipedia.org/wiki/Reflection_%28computer_programming%29" rel="nofollow" target="_blank"&gt;reflection&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I was reluctant to write the routine myself since the work is not trivial. It could get really nasty because there might be composition, aggregation and God knows what within an arbitrary object. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
So I waited….&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Just a few days ago, I realized that I could use the JSON marshalling and unmarshalling features introduced in Delphi (2010?) to write the &lt;b&gt;deep copy&lt;/b&gt; method. So I came with this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;br /&gt;
&amp;nbsp; DBXJSON, DBXJSONReflect;&lt;br /&gt;
.....&lt;br /&gt;
&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function DeepCopy(aValue: TObject): TObject;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MarshalObj: TJSONMarshal;&lt;br /&gt;
&amp;nbsp; UnMarshalObj: TJSONUnMarshal;&lt;br /&gt;
&amp;nbsp; JSONValue: TJSONValue;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= nil;&lt;br /&gt;
&amp;nbsp; MarshalObj := TJSONMarshal.Create;&lt;br /&gt;
&amp;nbsp; UnMarshalObj := TJSONUnMarshal.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue := MarshalObj.Marshal(aValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Assigned(JSONValue) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= UnMarshalObj.Unmarshal(JSONValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MarshalObj.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; UnMarshalObj.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
You can now use it like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; MyObject1,&lt;br /&gt;
&amp;nbsp; MyObject2: TMyObject;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Regular object construction&lt;br /&gt;
&amp;nbsp; MyObject1:= TMyObject.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Deep copying an object&lt;br /&gt;
&amp;nbsp; MyObject2:= TMyObject(DeepCopy(MyObject1));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject1.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject2.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
I tested it with some complex cases and it seems to be working quite well. Anyhow, if you find any problems or limitations, please, let me know.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Now that you get the idea we can do more crazy things like patching &lt;i&gt;TObject &lt;/i&gt;(or any other class hierarchy) by using &lt;i&gt;helpers&lt;/i&gt;. Look at this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp;&amp;nbsp; DBXJSON, DBXJSONReflect;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TObjectHelper = class helper for TObject&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; function Clone: TObject;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
function TObjectHelper.Clone: TObject;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MarshalObj: TJSONMarshal;&lt;br /&gt;
&amp;nbsp; UnMarshalObj: TJSONUnMarshal;&lt;br /&gt;
&amp;nbsp; JSONValue: TJSONValue;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= nil;&lt;br /&gt;
&amp;nbsp; MarshalObj := TJSONMarshal.Create;&lt;br /&gt;
&amp;nbsp; UnMarshalObj := TJSONUnMarshal.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue := MarshalObj.Marshal(Self);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Assigned(JSONValue) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= UnMarshalObj.Unmarshal(JSONValue);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JSONValue.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MarshalObj.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; UnMarshalObj.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
All of a sudden, &lt;i&gt;TObject &lt;/i&gt;has a &lt;i&gt;Clone &lt;/i&gt;method! Call it like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
.....&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; MyObject1,&lt;br /&gt;
&amp;nbsp; MyObject2: TMyObject;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Regular object construction&lt;br /&gt;
&amp;nbsp; MyObject1:= TMyObject.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Cloning an object&lt;br /&gt;
&amp;nbsp; MyObject2:= TMyObject(MyObject1.Clone);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Do something here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject1.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyObject2.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
If you think that &lt;i&gt;helpers &lt;/i&gt;are an aberration, you can still create a &lt;i&gt;TCloneable &lt;/i&gt;class with a &lt;i&gt;Clone&lt;/i&gt; method and inherit from it, right? You can even use the &lt;a href="http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html"&gt;decorator pattern&lt;/a&gt; to attach a &lt;i&gt;Clone &lt;/i&gt;method to an object. You can do more…Share it with me, please. Thanks!&lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/1098229902213601340/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/1098229902213601340?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/1098229902213601340?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html" title="Deep copying (cloning) objects in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;DUEBQ344eyp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-7202628466359617018</id><published>2012-01-26T15:01:00.016-05:00</published><updated>2012-12-13T20:14:12.033-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:14:12.033-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>String comparison in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
Have you ever wondered how utilities like &lt;b&gt;Beyond Compare&lt;/b&gt; or &lt;b&gt;DIFF &lt;/b&gt;are comparing files? They do it (I guess) by solving the &lt;a href="http://en.wikipedia.org/wiki/Longest_common_subsequence" rel="nofollow" target="_blank"&gt;longest common subsequence (LCS) problem&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
After reading the Wikipedia article linked above, I obtained an overall view of the problem and I looked at the possible resolutions. So, I decided to implement a Delphi class to do the string comparison trick, which is the base for the text file comparison.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Let me put it as follows: given two strings to be compared, I want to highlight in &lt;span style="color: blue;"&gt;blue &lt;/span&gt;the characters added to the first string and in &lt;span style="color: red;"&gt;red &lt;/span&gt;the characters removed from it. The common (unchanged) characters will keep the default color.&lt;/div&gt;
&amp;nbsp; &lt;br /&gt;
&lt;u&gt;For example: &lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
String 1 = &lt;i&gt;Delphi allows both structural and object oriented programming.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
String 2 = &lt;i&gt;Does Delphi allow object oriented programming?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Highlighted differences:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;Does &lt;/span&gt;Delphi allow&lt;span style="color: red;"&gt;s both structural and&lt;/span&gt; object oriented programming&lt;span style="color: red;"&gt;.&lt;/span&gt;&lt;span style="color: blue;"&gt;?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The Delphi class looks like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TDiff = record&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Character: Char;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharStatus: Char;&amp;nbsp; //Possible values: [+, -, =]&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TStringComparer = class&lt;br /&gt;
&amp;nbsp; ……………&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
When you call &lt;i&gt;TStringComparer.Compare&lt;/i&gt;, a generic list of &lt;i&gt;TDiff &lt;/i&gt;records is created. A &lt;i&gt;TDiff &lt;/i&gt;record contains a character and whether this character was added (&lt;i&gt;CharStatus &lt;/i&gt;= ‘+’), removed (&lt;i&gt;CharStatus &lt;/i&gt;= ‘-’) or unchanged (&lt;i&gt;CharStatus &lt;/i&gt;= ‘=’) in both strings under comparison.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Let’s drop two edits (&lt;i&gt;Edit1&lt;/i&gt;, &lt;i&gt;Edit2&lt;/i&gt;), a rich edit (&lt;i&gt;RichEdit1&lt;/i&gt;) and a button (&lt;i&gt;Button1&lt;/i&gt;) on a Delphi form. To highlight the differences put the following code in the &lt;i&gt;OnClick &lt;/i&gt;event of the button: &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.Button1Click(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Differences: TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; Diff: TDiff;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //Yes, I know...this method could be refactored ;-)&lt;br /&gt;
&amp;nbsp; Differences:= TStringComparer.Compare(Edit1.Text, Edit2.Text);&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.Clear;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelStart:= RichEdit1.GetTextLen;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for Diff in Differences do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Diff.CharStatus = '+' then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clBlue;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText := Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if Diff.CharStatus = '-' then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clRed;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText:= Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelAttributes.Color:= clDefault;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RichEdit1.SelText:= Diff.Character;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Differences.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
It looks like in the image below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a alt="String comparison in Delphi: The LCS problem" href="http://1.bp.blogspot.com/-gl3Ii9IsjhU/TyGv0Th6QjI/AAAAAAAAAIg/XbiVgfA5vMI/s1600/String-comparison-in-Delphi-LCS-problem.jpg" imageanchor="1" rel="nofollow" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-gl3Ii9IsjhU/TyGv0Th6QjI/AAAAAAAAAIg/XbiVgfA5vMI/s1600/String-comparison-in-Delphi-LCS-problem.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
For the full implementation read further down. Note that various optimizations could be added to the code below, but I didn’t implement them. Anyway, I hope this helps. Feedback is welcome! Feel free to find and correct bugs ;-)&lt;/div&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;code&gt;&lt;br /&gt;
unit StringComparison;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; Math, Generics.Collections;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TDiff = record&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Character: Char;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharStatus: Char;&amp;nbsp; //Possible values: [+, -, =]&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; TStringComparer = class&lt;br /&gt;
&amp;nbsp; strict private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; type TIntArray = array of array of Integer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function LCSMatrix(X, Y: string): TIntArray;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class procedure ComputeDifferences(aLCSMatrix: TIntArray;&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; X, Y: string;&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; i, j: Integer;&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; aDifferences: TList&amp;lt;TDiff&amp;gt;);&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TStringComparer }&lt;br /&gt;
&lt;br /&gt;
class function TStringComparer.LCSMatrix(X, Y: string): TIntArray;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; m, n,&lt;br /&gt;
&amp;nbsp; i, j: Integer;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; m:= Length(X);&lt;br /&gt;
&amp;nbsp; n:= Length(Y);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //We need one extra column and one extra row to be filled with zeroes&lt;br /&gt;
&amp;nbsp; SetLength(Result, m + 1, n + 1);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //First column filled with zeros&lt;br /&gt;
&amp;nbsp; for i := 0 to m do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, 0] := 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //First row filled with zeros&lt;br /&gt;
&amp;nbsp; for j:= 0 to n do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[0, j]:= 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Storing the lengths of the longest common subsequences&lt;br /&gt;
&amp;nbsp; //between prefixes of X and Y&lt;br /&gt;
&amp;nbsp; for i:= 1 to m do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for j:= 1 to n do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if X[i] = Y[j] then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, j] := Result[i-1, j-1] + 1&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[i, j]:= Max(Result[i, j-1], Result[i-1, j]);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class procedure TStringComparer.ComputeDifferences(aLCSMatrix: TIntArray;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; X, Y: string;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i, j: Integer;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences: TList&amp;lt;TDiff&amp;gt;);&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; CharDiff: TDiff;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if (i &amp;gt; 0) and (j &amp;gt; 0) and (X[i] = Y[j]) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i-1, j-1, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= X[i];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= '=';&amp;nbsp;&amp;nbsp; //The character did not change&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp; end&lt;br /&gt;
&amp;nbsp; else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (j &amp;gt; 0) and ((i = 0) or (aLCSMatrix[i,j-1] &amp;gt;= aLCSMatrix[i-1,j])) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i, j-1, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= Y[j];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= '+'; //The character was added&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else if (i &amp;gt; 0) and ((j = 0) or (aLCSMatrix[i,j-1] &amp;lt; aLCSMatrix[i-1,j])) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ComputeDifferences(aLCSMatrix, X, Y, i-1, j, aDifferences);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.Character:= X[i];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CharDiff.CharStatus:= '-'; //The character was removed&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aDifferences.Add(CharDiff);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
//This is a factory method&lt;br /&gt;
class function TStringComparer.Compare(aString1, aString2: string): TList&amp;lt;TDiff&amp;gt;;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; Matrix: TIntArray;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Result:= TList&amp;lt;TDiff&amp;gt;.Create;&lt;br /&gt;
&amp;nbsp; Matrix:= LCSMatrix(aString1, aString2);&lt;br /&gt;
&amp;nbsp; ComputeDifferences(Matrix,&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; aString1, aString2,&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; Length(aString1), Length(aString2),&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; Result);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/7202628466359617018/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/01/lcs-string-comparison-in-delphi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7202628466359617018?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7202628466359617018?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/01/lcs-string-comparison-in-delphi.html" title="String comparison in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-gl3Ii9IsjhU/TyGv0Th6QjI/AAAAAAAAAIg/XbiVgfA5vMI/s72-c/String-comparison-in-Delphi-LCS-problem.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUcBSH08eip7ImA9WhNWF0Q.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-4060170343467805884</id><published>2012-01-17T13:33:00.008-05:00</published><updated>2012-12-17T20:10:59.372-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-17T20:10:59.372-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="DUnit" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Testing the World Away: Recovery mission</title><content type="html">&lt;div style="font-family: inherit; text-align: justify;"&gt;
I was recently reviewing the &lt;a href="http://dunit.sourceforge.net/#Links" rel="nofollow" target="_blank"&gt;DUnit&lt;/a&gt; website and I noticed there is a broken link to an article titled “Testing The World Away”. It was written by Will Watts for QBS Software. November, 2000. &lt;br /&gt;
&lt;br /&gt;
I said “OK, maybe the article was relocated somewhere else in the QBS Software website”; so I tried a custom Google search &lt;a href="http://www.google.ca/search?as_q=&amp;amp;as_epq=Testing+the+World+Away&amp;amp;as_oq=&amp;amp;as_eq=&amp;amp;as_nlo=&amp;amp;as_nhi=&amp;amp;lr=&amp;amp;cr=&amp;amp;as_qdr=all&amp;amp;as_sitesearch=qbssoftware.com&amp;amp;as_occt=any&amp;amp;safe=images&amp;amp;tbs=&amp;amp;as_filetype=&amp;amp;as_rights=" rel="nofollow" target="_blank"&gt;"Testing the World Away" site:qbssoftware.com&lt;/a&gt;. As you can see the article was either banned from Google or removed completely from the QBS Software website.&lt;br /&gt;
&lt;br /&gt;
Once again I said “OK, maybe there’s a copy of the article somewhere else on the Internet” and I tried a second custom Google search &lt;a href="http://www.google.ca/search?as_q=&amp;amp;as_epq=Testing+the+World+Away&amp;amp;as_oq=&amp;amp;as_eq=&amp;amp;as_nlo=&amp;amp;as_nhi=&amp;amp;lr=&amp;amp;cr=&amp;amp;as_qdr=all&amp;amp;as_occt=any&amp;amp;safe=images&amp;amp;tbs=&amp;amp;as_filetype=&amp;amp;as_rights=" rel="nofollow" target="_blank"&gt;"Testing the World Away"&lt;/a&gt;. At this point I convinced myself that the article was gone for good.&lt;br /&gt;
&lt;br /&gt;
I am a curious guy, so I tried one final thing: I looked up the broken link[1] in the &lt;a href="http://www.archive.org/about/about.php" rel="nofollow" target="_blank"&gt;Internet Archive&lt;/a&gt; website and wallah!, they came with an archived version of the article.&lt;br /&gt;
&lt;br /&gt;
I have shared below a copy of the article so that we can take a look. As I said, this article is not mine, and if the author(owner) at some point request me to deleted it from my blog, I will do so.&lt;br /&gt;
&lt;br /&gt;
[1] &lt;a href="http://www.qbss.com/html/news/news_body.asp?content=ARTICLE&amp;amp;link=368&amp;amp;zone=" rel="nofollow" target="_blank"&gt;http://www.qbss.com/html/news/news_body.asp?content=ARTICLE&amp;amp;link=368&amp;amp;zone=&lt;/a&gt;&amp;nbsp; &lt;/div&gt;
&lt;div style="font-family: inherit; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: inherit; text-align: justify;"&gt;
&lt;span style="color: blue; font-size: small;"&gt;&lt;span class="COLOURED"&gt;&lt;b&gt;Testing the World Away&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;    &lt;/span&gt;&lt;span style="color: green; font-size: small;"&gt;&lt;b&gt;(01 November 2000)&lt;/b&gt;&lt;/span&gt;    &lt;/div&gt;
&lt;div style="font-family: inherit; text-align: justify;"&gt;
&lt;span style="color: black; font-size: small;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 style="font-family: inherit; text-align: justify;"&gt;
&lt;span style="color: black; font-size: small;"&gt;Testing the World Away&lt;/span&gt;&lt;/h2&gt;
&lt;div style="font-family: inherit; text-align: justify;"&gt;
&lt;span style="color: black; font-size: small;"&gt; The software methodology of the hour is Kent Beck’s ‘Extreme Programming’. Mr  Beck is a Smalltalk programmer by trade and, I think, a bit of a lad by  inclination (evidence: the bibliography of his book Extreme Programming  Explained, as well as citing standards such as The Mythical Man-Month and Design  Patterns, also recommends Cynthia Heimel’s Sex Tips for Girls. Right on!). I  find some of his ideas unconvincing. Pair Programming for example, where one  programmer sits at the keyboard and works while the other does something else -  possibly flower-arranging, my concentration lapsed at this point in the text as  I tried to imagine any manager I’ve met who would permit this exciting way of  increasing his costs - seems too beautiful and delicate for our mortal coil. On  the other hand his approach to testing, and the free libraries based on his  design that are around to back it up, comes much nearer to hitting, as I suppose  Ms Heimel might put it, my programming G-spot.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;span style="color: black; font-size: small;"&gt; Mr Beck’s idea is that as you write each bit of code, you should also write a  little test to go with it. As the project develops, the library of tests builds  up in parallel. After each alteration or addition, you rerun the test suite to  discover if you have broken anything. One of the rules - and I think it is an  important one - is that the test suite must be able to run all the way through,  pass or fail, without operator intervention. So although it is a chore to write  the tests, the effort put in is ‘banked’, and it costs very little to rerun them  - with the consequence that they do get rerun.&lt;br /&gt;
&lt;br /&gt;
Mr Beck has had brushes with those GUI automated tools that record keystrokes  and mouse-clicks into some sort of script and then let you play your actions  back at the application to be tested and verify its responses. These look like  they are going to do the job from the description on the packet but in practice,  as Mr Beck correctly observes, they are not very robust. Remove one edit box, or  merely nudge it three pixels to the right, or change the screen resolution -  suddenly the whole thing falls flat on its face. Testing code, he decided,  should be written at the same level and in the same language as the stuff to be  tested.&lt;br /&gt;
&lt;br /&gt;
Tests also need structure. One needs to see results presented in a consistent  way, to be able to select specific tests to run and so on. To this end, Mr Beck  wrote a library of Smalltalk classes - a framework - called ‘SmalltalkUnit’ or  ‘SUnit’. Later on he collaborated with no less than Erich Gamma to produce a  Java version called ‘JUnit’. The idea ‘took on’, and now there are versions for  an impressive range of languages including C++, Eiffel, Objective-C, Perl,  Python, Visual Basic and even Visual Objects. You'll find them all listed at  &lt;a href="http://www.xprogramming.com/software.htm" rel="nofollow" target="_blank"&gt;http://www.xprogramming.com/software.htm&lt;/a&gt;.  If you are familiar with my language prejudices, you will be unsurprised to  learn that I am going to discuss a Delphi language version called DUnit.  Originally ported from the Java version by Juancarlo Añez, this library is now  maintained on an Open Source basis by the DUnit group at SourceForge:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://sourceforge.net/projects/dunit/" rel="nofollow" target="_blank"&gt;https://sourceforge.net/projects/dunit/&lt;/a&gt;.  This library makes heavy use of function overloading, so you’ll need Delphi 4 or  later to play with it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Who DUnit?&lt;/b&gt;&lt;br /&gt;
Figure 1 shows a suite of DUnit tests that  have been run using the library’s GUI interface. The top pane lists all the  tests available. These are organised in a hierarchy: a suites of tests may  contain either individual test cases or other suites - a Composite pattern. In  the part of the hierarchy visible, I have set up a suite called ‘SFW COM Library  tests’ that, in turn, contains suites subdivided by the class being tested. The  TTestDoubleChannel suite operates on a class called TDoubleChannel, and below  TTestDoubleChannel are tests on individual methods. There are checkboxes to  switch individual tests and parts of the hierarchy on and off; these interact  with some useful buttons at the bottom of the dialog to allow speedy selection  of all or part of the suite.&lt;br /&gt;
&lt;br /&gt;
Each test is colour-coded by the result of the last run. Green, obviously,  indicates success; magenta a ‘failure’, that is that an unexpected result was  obtained; red, an ‘error’, that the test threw an exception. The lower pane  lists all the failures and errors together with descriptive messages. In between  the two panes are progress bars indicating progress through the test suite and  success rate.&lt;br /&gt;
&lt;br /&gt;
Figure 2 shows DUnit’s text mode version after running the same test suite as  Figure 1, and I hope that you can see it has produced the same results. Although  lacking the eye candy and versatility of the GUI test runner, this console  version requires no interaction and sets its exit code non-zero on failure. This  makes it ideal for placing in a make file, or incorporating into an automated  testing procedure. By the way, to make my test suite code run as a console  application, I substituted one .DPR file for another - about 10 seconds’  work.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How it works&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The key class in DUnit’s framework is &lt;i&gt;TTestCase&lt;/i&gt;. All the actual  testing code is placed in classes that you derive from it. It’s easiest to see  how this works with a snippet of code. Figure 3 shows a trivial example of a  program that tests 1 + 1 = 2.&lt;br /&gt;
&lt;br /&gt;
First look at the Project1TestCases.pas unit. TTestCaseFirst is derived from  TTestCase, adding one published method testFirst. Three features of this method  are important: that it is a parameterless procedure, that it has public scope,  and that its name begins ‘test…’. These features enable DUnit to discover and  run the method without the need to call it explicitly in hand-generated code. It  is sufficient to declare a method of a TTestCase-derived class that follows  these rules to get it run.&lt;br /&gt;
&lt;br /&gt;
The implementation of testFirst is a single line: I ‘assert’ that 1 + 1 = 2.  (Old Delphi hands and practitioners of design-by-contract may be raising their  eyebrows at this strange use of Assert. Please bear with me, explanations and  excuses will follow in due course.)&lt;br /&gt;
&lt;br /&gt;
At the bottom of Project1TestCases.pas, in an initialization section, is the  call registerTest('', TTestCaseFirst); which registers TTestCaseFirst with the  framework. The first parameter is the ‘path’, it controls where a test case  appears in the hierarchy. By supplying an empty string I am placing it below the  root node.&lt;br /&gt;
&lt;br /&gt;
The project file Project1Test.dpr references DUnit library units  TestFrameWork and &lt;i&gt;GUITestRunner&lt;/i&gt; as well as Project1TestCases.pas. A  single line replaces the standard Delphi GUI project code:  &lt;i&gt;GUITestRunner.runTest(TestFramework.registeredTests);&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
This creates and displays the GUI interface shown in Figure 1. And that’s it.  To add further arithmetic tests, just write extra test… methods, for example&lt;br /&gt;
&lt;br /&gt;
procedure TTestCaseFirst.testSecond;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Assert(2 + 2 = 5,  'Oops!');&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
This mistake will be flagged as a magenta-coloured failure when it is run.&lt;br /&gt;
&lt;br /&gt;
In reality one uses DUnit on classes rather than trivial arithmetic.  Instances of classes can be placed as member data in the TTestCase-derived  class, and two virtual methods, SetUp and TearDown, can be overridden to create  and destroy them around each test method. Figure 4 sketches how this is done.  Note that SetUp is called before, and TearDown after, each test method. This  isolation of the test methods from each other is deliberate - you shouldn’t  build a sequence of tests where one method is dependant on those called  before.&lt;br /&gt;
I mentioned DUnit’s ability to build up suites from multiple test cases. This  is accomplished using the TTestSuite class:&lt;br /&gt;
&lt;i&gt;Suite := TTestSuite.create('A  suite');&lt;br /&gt;
Suite.addTests(TTestCaseFirst);&lt;br /&gt;
Suite.addTests(TTestCaseMyClass);&lt;/i&gt;&lt;br /&gt;
The populated suite can then be passed to registerTest as before.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All About Assert&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It’s time to own up to a problem with DUnit. The library’s use of the Assert  function to check the test conditions is rather perverse. Assert already has a  well-understood role in Delphi code, and this isn’t it. How did it get there?  Well, you will recall that DUnit is a port of a Java library called JUnit and  the Java language, I am informed, doesn’t have an Assert in the C++/Delphi  sense. Unfortunately the ‘Assert’ name was carried across with the rest of  JUnit. An easy mistake to make:&amp;nbsp; it has also happened to the people doing a  C++ version of JUnit.&lt;br /&gt;
&lt;br /&gt;
However, there is a move afoot among the DUnit developers to change the  function's name, probably to Check, and also to add a family of useful  overloaded methods with names like CheckEqual, CheckNotEqual and so on. With  luck this will have gone through by the time you read this.&lt;br /&gt;
&lt;br /&gt;
DUnit is very much work-in-progress, and there are a number of interesting  additions and enhancements coming into view. Two add-ons have just been released  - one standalone, one integrated with the IDE enhancer CodeRush - which will  generate skeleton test case code from the declaration of a class that is to be  tested. As well as extra facilities for test repetition and set-up that I have  not covered here, there are also plans to add special support for databases,  multi-threading and GUI testing.&lt;br /&gt;
&lt;br /&gt;
No technique can stop testing from being a fag. But I have found that the  accumulation of a permanent test suite, and the improved confidence in my code  developed in this way make DUnit’s use worthwhile. Go on: pull it down and have  a go!&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Will Watts is a programmer and occasional journo who lives in Chiswick.  To his pleasure, his Snobol column in Developers Review has not, as far as he  knows, been nominated for the Worst IT Journalism 2000 Award.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Books:&lt;/b&gt;&lt;br /&gt;
Extreme Programming Explained by Kent Beck, pub  Addison-Wesley, ISBN 0-201-61641-6. Mr Beck’s philosophy of software  development.&lt;br /&gt;
Refactoring - Improving the Design of Existing Code by Martin  Fowler et al, pub Addison-Wesley, ISBN 0-201-48567-2. Includes good description  of JUnit.&lt;/span&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/4060170343467805884/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/01/testing-world-away.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4060170343467805884?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4060170343467805884?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/01/testing-world-away.html" title="Testing the World Away: Recovery mission" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;CUcCSXkzeSp7ImA9WhNWEUw.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-5986191213346584173</id><published>2012-01-11T16:34:00.040-05:00</published><updated>2012-12-09T23:17:48.781-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-09T23:17:48.781-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="immigration" /><category scheme="http://www.blogger.com/atom/ns#" term="Canada" /><category scheme="http://www.blogger.com/atom/ns#" term="Toronto" /><category scheme="http://www.blogger.com/atom/ns#" term="tips for immigrants" /><category scheme="http://www.blogger.com/atom/ns#" term="I-94" /><category scheme="http://www.blogger.com/atom/ns#" term="nonimmigrant visas" /><category scheme="http://www.blogger.com/atom/ns#" term="I-94 Form" /><category scheme="http://www.blogger.com/atom/ns#" term="visitor visas" /><category scheme="http://www.blogger.com/atom/ns#" term="US" /><category scheme="http://www.blogger.com/atom/ns#" term="immigrant" /><title>Multiple Entries to the US with the same I-94 Form: Just for Canadian Residents</title><content type="html">&lt;div style="text-align: justify;"&gt;
I am a Permanent Resident of Canada (Landed Immigrant) and &lt;a href="http://www.yanniel.info/2011/10/us-visitor-visa-for-canadian-residents.html"&gt;I got a B-2 Visitor Visa&lt;/a&gt; which I used in order to travel to the United States of America for 15 days.&lt;br /&gt;
&lt;br /&gt;
I crossed the border at the Rainbow Bridge at Niagara Falls. In the American side of the bridge there is a US Point of Entry, in which I was requested for my papers. I presented my Cuban Passport with a one time B-2 Visitor Visa to the American Officer controlling the crossing. The officer kept my passport and redirected me to one office located just a few meters further. &lt;br /&gt;
&lt;br /&gt;
I waited for 40 minutes and I was called for an interview with another officer. He asked for the purpose of the trip, the intended duration of the stay, my destinations within the States, the means of returning back (flight and bus tickets) [1], my relation to the people I was visiting in the US, and things like that. &lt;br /&gt;
&lt;br /&gt;
The officer issued an I-94 Form, that he stapled onto my passport. I paid a $6.00 USD fee for the I-94 Form and my passport was returned to me. [Make sure you have exactly $6.00 USD (cash) if you want to get this done quickly. You can pay with credit card as well, but it takes more time]&lt;br /&gt;
&lt;br /&gt;
The I-94 Form was issued for 6 moths, meaning that I was permitted to stay in the US until the expiry date, 6 months later.&lt;br /&gt;
&lt;br /&gt;
In my way back to Canada I crossed the Rainbow Bridge again (in the opposite direction). This time I was stopped by a Canadian Custom Officer. She asked for my papers: I gave her my passport and my Canadian Resident Card [2]. She asked pretty much the same questions that the American Officer did, and she also inquired about any merchandize that I was bringing from the US. &lt;br /&gt;
&lt;br /&gt;
I was expecting her to remove the I-94 from the passport, but she didn’t. Usually, you need to surrender your I-94 when leaving the US, but it seems that Canadian Residents can use the same I-94 Form (if not expired) to re-entry to the US multiple times. It seems that you can do this regardless of the validity of your Visa: the only thing taken into consideration is that the I-94 Form has to be valid.&lt;br /&gt;
&lt;br /&gt;
Looking for a validation for my theory I found &lt;a href="http://discuss.ilw.com/eve/forums/a/tpc/f/902603441/m/4086059853" rel="nofollow" target="_blank"&gt;this post&lt;/a&gt;. I am extracting the main juice below:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;You don't have to get a new I-94 every time &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;you enter the USA. How do I know ?, because &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;I've being traveling to the USA for the past &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;4.5 years and using the same I-94 until its &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;expiry date. In fact the INS officer told me &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;that I did not have to turn in the I-94 if I &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;intent to enter the USA prior to the expiry &lt;/i&gt;&lt;br /&gt;
&lt;i&gt;date.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
I also talked to a few friends who confirmed that they used the I-94 Form to re-enter the US from Canada, even after their visa was expired.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
I looked furthermore to validate this theory and I found out that:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;If taking short trips (30 days or less) to Canada, Mexico, or the Caribbean Islands during the course of your visit to the U.S., hold onto your I-94 or I-94 (W); it should only be turned in when you leave the U.S. to return home.&lt;/i&gt; [&lt;a href="http://photos.state.gov/libraries/macedonia/8573/ArchivePDFNov2010/New_I-94_FormNov2010.pdf" rel="nofollow" target="_blank"&gt;U.S. Department of State&lt;/a&gt;]&lt;br /&gt;
&lt;br /&gt;
After this I was pretty confident of my theory and I went to the US a second time. This time I crossed the border at the Peace Bridge. I was not expecting any problems: my visa was expired, but my I-94 was not. You know what? I did have a problem…&lt;br /&gt;
&lt;br /&gt;
The American officer told me that they allow most people visiting the US to re-enter by just using the I-94 (if not expired). The problem in my case is that I am a Cuban national. Cubans (among other nationalities) are taken especial care by the US government. That meant that I was not able to use my I-94 Form to re-enter the US.&lt;br /&gt;
&lt;br /&gt;
I was very disappointed, but the American officer wanted to support my case. She noticed that I made an honest mistake. So, she took my finger prints, made me fill some forms and with that, she supported my case with her superiors. Not even her immediate superior was able to allow me enter the US. So, the whole process took like 3 hours and of course, I lost my bus and the plain. &lt;br /&gt;
&lt;br /&gt;
After all this they gave me a waiver, which is a one time permit to enter the US without a visa. I was glad at this point, because those Americans officers helped me while they were enforcing the law. They removed the original 6 months I-94 from my passport, and they re-issued a new one for just one week (I was going this time for the weekend; so it was good enough for me).&lt;br /&gt;
&lt;br /&gt;
They explicitly told me to surrender this new I-94 Form to the Canadian custom officer in my way back to Canada. I did that of course. Note that you have to advise the Canadian officer to remove the I-94 from your passport. The Canadian officer does not remove it if you don’t ask.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: black;"&gt;
&lt;b&gt;So, the conclusion if that you can use the I-94 Form (if not expired) to re-enter the US from Canada, but this does NOT apply to nationals of Cuba, Iran, Syria, and Sudan. This &lt;a href="http://www.state.gov/j/ct/c14151.htm" rel="nofollow" target="_blank"&gt;list&lt;/a&gt; could change at any moment.&lt;/b&gt;&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="color: red;"&gt;Disclaimer: This is based on my own experience as a Permanent Resident of Canada. You should not consider this a legal advice or whatsoever. &lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Just one more thing, after all this hassle I got a new &lt;a href="http://www.yanniel.info/2011/10/us-visitor-visa-for-canadian-residents.html"&gt;B2-Visitor Visa&lt;/a&gt; to enter the US. So, I will be going soon to the States. This time I don’t expect any problems :-)&lt;/div&gt;
&lt;br /&gt;
[1]: I was traveling from Toronto to Buffalo by land; passing though Niagara Falls. Then, I was traveling from Buffalo to Miami by air. I used that route backwards in my way back.&lt;br /&gt;
[2]: Don’t forget your Canadian Resident Card. You need it to re-enter Canada.&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/5986191213346584173/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/01/re-entry-us-unexpired-i-94-form.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/5986191213346584173?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/5986191213346584173?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/01/re-entry-us-unexpired-i-94-form.html" title="Multiple Entries to the US with the same I-94 Form: Just for Canadian Residents" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUAGQHs4fSp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-8418763582187933434</id><published>2012-01-09T18:04:00.011-05:00</published><updated>2012-12-13T20:15:21.535-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:15:21.535-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="API" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Delphi Implementation for the OpenSubtitles API</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;a href="http://www.opensubtitles.org/" rel="nofollow" target="_blank"&gt;OpenSubtitles.org&lt;/a&gt; allows searching and hosting subtitles in several formats (SRT, SUB, etc.) and pretty much every language. It currently has a vast database of subtitles (expanding every day). OpenSubtitles.org also exposes a XML-RPC based API that can be used in order to build third party applications with subtitle features.&lt;br /&gt;
&lt;br /&gt;
I am writing a Delphi app to search subtitles in the OpenSubtitles.org database... I thought it would be nice to have a Delphi wrapper for the whole API. Below is my three cents contribution. I will probably implement and share more methods in the future, but feel free to contribute as well.&amp;nbsp; Take a look at the &lt;a href="http://trac.opensubtitles.org/projects/opensubtitles/wiki/XMLRPC" rel="nofollow" target="_blank"&gt;full API methods list&lt;/a&gt;.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
XML-RPC stands for XML Remote Procedure Call. It allows “remote procedure calling using HTTP as the transport and XML as the encoding”. [&lt;a href="http://xmlrpc.scripting.com/spec" rel="nofollow" target="_blank"&gt;http://xmlrpc.scripting.com/spec&lt;/a&gt;]. XML-RPC is really easy to implement: in the code below I have used formatted strings to conform the XML requests (XML encoding pending) and the Indy TIdHTTP component to send the requests. &lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
unit OpensubtitlesAPI;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; IdHTTP, Classes, SysUtils;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; function LogIn(aUsername, aPassword,&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; aLanguage, aUserAgent: string): string;&lt;br /&gt;
&amp;nbsp; function LogOut(aToken: string): string;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID,&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; aMovieHash: string;&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; aMovieByteSize: Cardinal): string;&amp;nbsp; overload;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID: string;&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; aImdbID: Cardinal): string; overload;&lt;br /&gt;
&amp;nbsp; function SearchSubtitles(aToken, aSublanguageID,&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; aQuery: string): string;&amp;nbsp; overload;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
function XML_RPC(aRPCRequest: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; cURL= 'http://api.opensubtitles.org/xml-rpc';&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; lHTTP: TIdHTTP;&lt;br /&gt;
&amp;nbsp; Source,&lt;br /&gt;
&amp;nbsp; ResponseContent: TStringStream;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; lHTTP := TIdHTTP.Create(nil);&lt;br /&gt;
&amp;nbsp; lHTTP.Request.ContentType := 'text/xml';&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Accept := '*/*';&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Connection := 'Keep-Alive';&lt;br /&gt;
&amp;nbsp; lHTTP.Request.Method := 'POST';&lt;br /&gt;
&amp;nbsp; lHTTP.Request.UserAgent := 'OS Test User Agent';&lt;br /&gt;
&amp;nbsp; Source := TStringStream.Create(aRPCRequest);&lt;br /&gt;
&amp;nbsp; ResponseContent:= TStringStream.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lHTTP.Post(cURL, Source, ResponseContent);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= ResponseContent.DataString;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= '';&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; lHTTP.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Source.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ResponseContent.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LogIn(aUsername, aPassword, aLanguage, aUserAgent: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; LOG_IN = '&amp;lt;?xml version="1.0"?&amp;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;lt;methodCall&amp;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;lt;methodName&amp;gt;LogIn&amp;lt;/methodName&amp;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;lt;params&amp;gt;'&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;&amp;nbsp; &amp;lt;param&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%3:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;/params&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;lt;/methodCall&amp;gt;';&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(LOG_IN, [aUsername, aPassword, aLanguage, aUserAgent]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function LogOut(aToken: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; LOG_OUT = '&amp;lt;?xml version="1.0"?&amp;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;lt;methodCall&amp;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;lt;methodName&amp;gt;LogOut&amp;lt;/methodName&amp;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;lt;params&amp;gt;'&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;&amp;nbsp; &amp;lt;param&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;/params&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;lt;/methodCall&amp;gt;';&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(LOG_OUT, [aToken]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID, aMovieHash: string; aMovieByteSize: Cardinal): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = '&amp;lt;?xml version="1.0"?&amp;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;lt;methodCall&amp;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;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;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;lt;params&amp;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;lt;param&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&amp;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;lt;value&amp;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;lt;array&amp;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;lt;data&amp;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;lt;value&amp;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;lt;struct&amp;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;lt;member&amp;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;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;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;lt;/value&amp;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;lt;/member&amp;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;lt;member&amp;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;lt;name&amp;gt;moviehash&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/member&amp;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;lt;member&amp;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;lt;name&amp;gt;moviebytesize&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;double&amp;gt;%3:d&amp;lt;/double&amp;gt;&amp;lt;/value&amp;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;lt;/member&amp;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;lt;/struct&amp;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;lt;/value&amp;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;lt;/data&amp;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;lt;/array&amp;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;lt;/value&amp;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;lt;/param&amp;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;lt;/params&amp;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;lt;/methodCall&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aMovieHash, aMovieByteSize]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID: string;&lt;br /&gt;
&amp;nbsp; aImdbID: Cardinal): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = '&amp;lt;?xml version="1.0"?&amp;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;lt;methodCall&amp;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;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;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;lt;params&amp;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;lt;param&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&amp;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;lt;value&amp;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;lt;array&amp;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;lt;data&amp;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;lt;value&amp;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;lt;struct&amp;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;lt;member&amp;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;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;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;lt;/value&amp;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;lt;/member&amp;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;lt;member&amp;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;lt;name&amp;gt;imdbid&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:d&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/member&amp;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;lt;/struct&amp;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;lt;/value&amp;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;lt;/data&amp;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;lt;/array&amp;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;lt;/value&amp;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;lt;/param&amp;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;lt;/params&amp;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;lt;/methodCall&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aImdbID]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function SearchSubtitles(aToken, aSublanguageID,&lt;br /&gt;
&amp;nbsp; aQuery: string): string;&lt;br /&gt;
const&lt;br /&gt;
&amp;nbsp; SEARCH_SUBTITLES = '&amp;lt;?xml version="1.0"?&amp;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;lt;methodCall&amp;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;lt;methodName&amp;gt;SearchSubtitles&amp;lt;/methodName&amp;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;lt;params&amp;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;lt;param&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%0:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/param&amp;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;lt;param&amp;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;lt;value&amp;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;lt;array&amp;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;lt;data&amp;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;lt;value&amp;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;lt;struct&amp;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;lt;member&amp;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;lt;name&amp;gt;sublanguageid&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%1:s&amp;lt;/string&amp;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;lt;/value&amp;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;lt;/member&amp;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;lt;member&amp;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;lt;name&amp;gt;query&amp;lt;/name&amp;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;lt;value&amp;gt;&amp;lt;string&amp;gt;%2:s&amp;lt;/string&amp;gt;&amp;lt;/value&amp;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;lt;/member&amp;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;lt;/struct&amp;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;lt;/value&amp;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;lt;/data&amp;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;lt;/array&amp;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;lt;/value&amp;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;lt;/param&amp;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;lt;/params&amp;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;lt;/methodCall&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //TODO: XML Encoding&lt;br /&gt;
&amp;nbsp; Result:= XML_RPC(Format(SEARCH_SUBTITLES, [aToken, aSublanguageID, aQuery]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end. &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Finally, I present you some sample calls:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Logging- in anonymously (empty credentials) and getting the token: &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;LogIn('', '', 'en', 'OS Test User Agent');&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Logging- out (disposing the token): &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;LogOut(&lt;/code&gt;&lt;code&gt;'&lt;/code&gt;&lt;code&gt;81nt6bgl9vde06l3ptq7v1a7r1&lt;/code&gt;&lt;code&gt;'&lt;/code&gt;&lt;code&gt;);&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for the movie whose ImdbID is &lt;i&gt;120737&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, 'eng', 120737);&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for &lt;i&gt;The Lord of the Rings&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, 'eng', 'The Lord of the Rings');&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Search English subtitles for the movie whose hash is &lt;i&gt;7d9cd5def91c9432 &lt;/i&gt;and size is &lt;i&gt;735934464&lt;/i&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;SearchSubtitles(Edit1.Text, 'eng', '7d9cd5def91c9432', 735934464);&lt;/code&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/8418763582187933434/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2012/01/open-subtitles-api-in-delphi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/8418763582187933434?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/8418763582187933434?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2012/01/open-subtitles-api-in-delphi.html" title="Delphi Implementation for the OpenSubtitles API" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUAAR3w6cSp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-916727228547268188</id><published>2011-12-14T13:18:00.019-05:00</published><updated>2012-12-13T20:15:46.219-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:15:46.219-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="PageRank" /><title>Request the Google PageRank the Delphi way</title><content type="html">&lt;div style="text-align: justify;"&gt;
In this post I am implementing the Delphi way to request the&lt;a href="http://en.wikipedia.org/wiki/PageRank#Google_Toolbar" rel="nofollow" target="_blank"&gt; Google Toolbar’s PageRank&lt;/a&gt; (PR). As an example, if I want to look up the PR of my blog (http://www.yanniel.info/), I will have to query the following URL: &lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/" rel="nofollow" target="_blank"&gt;http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So, if you try&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
Writeln(Curl('http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=64012521073&amp;amp;q=info:http://www.yanniel.info/'));&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
You will get the following output:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rank_1:1:0&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Oops, at this moment my PageRank is pathetic (PR = 0). Hopefully it will get better someday ;-)&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
You can find the implementation of the &lt;i&gt;Curl &lt;/i&gt;function in my previous post: &lt;a href="http://www.yanniel.info/2011/02/fetch-web-page-delphi-curl-indy.html" target="_blank"&gt;Fetching a web page with Delphi&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Now that you get the idea, it’s time to generalize our implementation in order to get the PR of any web page.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
In the URL above there are two dynamic parameters that we need to understand:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Parameter &lt;b&gt;q:&lt;/b&gt; This is the concatenation of “info:” plus the encoded URL for which we want to get the PR. It is mandatory to lead the encoded URL with “http://”. Don’t forget to put a “/” after the top domain, ei, “.info/”, not “.info”. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Parameter &lt;b&gt;ch&lt;/b&gt;: Obtaining this parameter is the tricky part. We have to hash the concatenation of “info:” plus our target URL (ei. http://www.yanniel.info/) using the &lt;a href="http://burtleburtle.net/bob/hash/perfect.html" rel="nofollow" target="_blank"&gt;minimal perfect hashing&lt;/a&gt; algorithm invented by Bob Jenkins. The outcome will be a number, which corresponds to the value of our &lt;b&gt;ch&lt;/b&gt; parameter. We are hashing something like “info:http://www.yanniel.info/”.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I didn’t have the time (or the desire) to understand and implement the minimal perfect hashing algorithm from scratch. So, I ported this &lt;a href="http://www.codeproject.com/KB/aspnet/Google_Pagerank.aspx" rel="nofollow" target="_blank"&gt;C# implementation&lt;/a&gt; into Delphi code. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
There’s one detail worth mentioning about the implementation. In the original C# code there’s a switch statement that falls all the way through the different cases. I needed to combine a &lt;i&gt;case&lt;/i&gt; statement and some &lt;i&gt;goto &lt;/i&gt;statements in order to accomplish the same in Delphi. &lt;strike&gt;Really, I tried to avoid the &lt;i&gt;goto&lt;/i&gt;, I always do, but I couldn’t find a better and cleaner way of implementation. I was telling myself how bad programmer I was, and then, I read one entry in &lt;a href="http://www.delphifeeds.com/" rel="nofollow" target="_blank"&gt;Delphi Feeds&lt;/a&gt; talking about the minimal perfect hashing algorithm, and more than that, highlighting the &lt;i&gt;goto &lt;/i&gt;issue. Nick Hodges wrote the &lt;a href="http://www.nickhodges.com/post/Flotsam-and-Jetsam-51.aspx" rel="nofollow" target="_blank"&gt;post&lt;/a&gt;: thank you Nick... now I can sleep again.&lt;/strike&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;strike&gt;It seems that I am not the only one considering this &lt;i&gt;goto &lt;/i&gt;usage as an exception to the good practice of “don’t use goto statements”. The funny thing is that I read Nick’s post without the intention of finding anything about the minimal perfect hashing algorithm or about the &lt;i&gt;goto &lt;/i&gt;stuff. It’s really a big coincidence that we were considering to write about the minimal perfect hashing algorithm (and the &lt;i&gt;goto &lt;/i&gt;gotcha) at the same time. &lt;/strike&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;I wrote the strikeout text above initially; but Brian (first comment below) found a clean way to avoid the &lt;i&gt;goto &lt;/i&gt;in this situation. I really thank Brian for his contribution, and next time, I won't quit that easily in removing the &lt;i&gt;goto &lt;/i&gt;;&lt;/span&gt;&lt;span style="color: blue;"&gt;-&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I am putting everything together in the Delphi console application below. I bet you can reuse the &lt;i&gt;BobJenkinsHash &lt;/i&gt;function in the &lt;i&gt;Generics.Default.pas&lt;/i&gt; unit to make the PR implementation more compact. I didn’t know about the &lt;i&gt;BobJenkinsHash &lt;/i&gt;function shipped with Delphi before reading Nick’s post; which is why I am keeping my original implementation.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Finally, this is how you request the Google PageRank in Delphi:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;program Project1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$APPTYPE CONSOLE}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$R *.res}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; System.SysUtils, IdHTTP, IdURI, Classes;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;type&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp; TByteArray =&amp;nbsp; array of Byte;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function Curl(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;const&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; cUSER_AGENT = 'Mozilla/4.0 (MSIE 6.0; Windows NT 5.1)';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHTTP: TIdHTTP;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Stream: TStringStream;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result := '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; IdHTTP := TIdHTTP.Create(nil);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Stream := TStringStream.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Request.UserAgent := cUSER_AGENT;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Get(aURL, Stream);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := Stream.DataString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stream.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdHTTP.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Hashing(var a, b, c: Integer);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 13);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b xor (a shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 13);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 12);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:=&amp;nbsp; b xor (a shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 5);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= a xor (c shr 3);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - c;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= b xor (a shl 10);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - a;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c - b;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c xor (b shr 15);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function StrOrd(aValue: string): TByteArray;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; I: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; SetLength(Result, Length(aValue));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; for I:= 1 to Length(aValue) do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result[I-1]:= Ord(aValue[I]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function PerfectHash(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; url: TByteArray;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _length,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; k, len: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a, b, c: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;label&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; One,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Two,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Three,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Four,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Five,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Six,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Seven,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Eight,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Nine,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Ten;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; url:= StrOrd(aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; _length:= Length(url);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; k:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; len:= _length;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; a:= $9E3779B9;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; b:= $9E3779B9;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= $E6359A60;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; while (len &amp;gt;= 12) do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 0] + (url[k + 1] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 2] shl 16) + (url[k + 3] shl 24) );&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 4] + (url[k + 5] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 6] shl 16) + (url[k + 7] shl 24) );&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c+ (url[k + 8] + (url[k + 9] shl 8) +&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (url[k + 10] shl 16) + (url[k + 11] shl 24));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Hashing(a, b, c);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; k:= k + 12;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; len:= len - 12;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; c:= c + integer(_length);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; case len of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11: begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 10] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Ten;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10: begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ten:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 9] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Nine;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Nine:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c:= c + (url[k + 8] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Eight;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Eight:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 7] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Seven;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seven:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 6] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Six;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Six:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 5] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Five;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Five:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b:= b + (url[k + 4]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Four;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Four:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 3] shl 24);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Three;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Three:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 2] shl 16);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto Two;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Two:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 1] shl 8);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; goto One;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1:&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; One:&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a:= a + (url[k + 0]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Hashing(a, b, c);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= Format('6%0:u', [c]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function GetPageRank(aURL: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;const&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; cToolbarQueriesURL = 'http://toolbarqueries.google.com/tbr?client=navclient-auto&amp;amp;features=Rank&amp;amp;ch=%0:s&amp;amp;q=%1:s';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; CH, Q: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aURL:= StringReplace(aURL, 'http://', '', []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if Pos('/', aURL) = 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aURL:= aURL + '/';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aURL:= 'http://' + aURL;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; CH:= PerfectHash('info:' + aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Q:= 'info:' + TIdURI.URLEncode(aURL);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= Curl(Format(cToolbarQueriesURL, [CH, Q]));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank('http://www.yanniel.info/'));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank('http://www.delphifeeds.com/'));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Writeln(GetPageRank('http://www.google.com/'));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/916727228547268188/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/12/google-pagerank-in-delphi.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/916727228547268188?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/916727228547268188?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/12/google-pagerank-in-delphi.html" title="Request the Google PageRank the Delphi way" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DUACQXk6eip7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-4798569634632094914</id><published>2011-12-09T11:08:00.013-05:00</published><updated>2012-12-13T20:16:00.712-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:16:00.712-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Pascal" /><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Script" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Pascal Server Pages – Pascal Script</title><content type="html">&lt;div style="text-align: justify;"&gt;
Without getting too technical, I would define a Pascal Server Page (PSP) as a dynamic web page containing embedded Pascal Script (PS) code.&amp;nbsp; When a web request is made, the PS code needs to be executed (interpreted) in the server side and outputted into the proper format (HTML, XML, JSON, text, etc). A PSP is commonly stored as a text file in the Web Server and it could be a mixture of PS code plus any other static content. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
This is an example of PSP:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;head&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;This is a Pascal Server Page&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/head&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;body&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;% begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write('Hello World');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;I am going to use Pascal Script to write a few numbers...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;% var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i:=1 to 10 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(i);&amp;nbsp; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
The code above is an HTML armature containing some PS code. The PS code has been isolated within the “&amp;lt;%” and “%&amp;gt;” tokens. The PS code is executed in the server and the output (if any) is embedded into the HTML template.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
So, if a browser asks for the page above, it will actually get plain HTML code as the one below:&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;head&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;This is a Pascal Server Page&amp;lt;/title&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/head&amp;gt;&amp;nbsp; &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;body&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Hello World&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p&amp;gt;I am going to use Pascal Script to write a few numbers...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;lt;br&amp;gt;2&amp;lt;br&amp;gt;3&amp;lt;br&amp;gt;4&amp;lt;br&amp;gt;5&amp;lt;br&amp;gt;6&amp;lt;br&amp;gt;7&amp;lt;br&amp;gt;8&amp;lt;br&amp;gt;9&amp;lt;br&amp;gt;10&amp;lt;br&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; &amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
This is all good. The only problem is that the PS code is not going to be magically executed. We need a server side component to do the PS interpretation.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I have seen a couple of intents to build such server side component in the Internet. Anyhow, I bring you my own proposal: create a Web Broker application with Pascal Scripting capabilities. To provide the &lt;a href="http://docwiki.embarcadero.com/RADStudio/XE2/en/Using_Web_Broker_Index" rel="nofollow" target="_blank"&gt;Web Broker&lt;/a&gt; application with the scripting capabilities, I will use &lt;a href="http://www.remobjects.com/ps.aspx" rel="nofollow" target="_blank"&gt;Pascal Script from RemObjects&lt;/a&gt;. You need to &lt;a href="http://www.remobjects.com/trials.aspx#free" rel="nofollow" target="_blank"&gt;download&lt;/a&gt; and install Pascal Script if you want to try my code.&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
The workflow goes as follows:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;The Web Broker application receives a Web Request.&lt;/li&gt;
&lt;li&gt;The Web Broker application finds the corresponding Pascal Server Page and loads its content to a buffer variable.&lt;/li&gt;
&lt;li&gt;The content of the buffer variable is parsed in order to find the PS tokens (I will use &lt;a href="http://docwiki.embarcadero.com/VCL/en/RegularExpressions.TRegEx" rel="nofollow" target="_blank"&gt;RegEx&lt;/a&gt; to do the parsing). &lt;/li&gt;
&lt;li&gt;Each PS block is compiled to Bytecode and then executed in the server. (I will use the Pascal Script library from RemObjects for this purpose).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The output generated from the execution of each PS block replaces its corresponding “&amp;lt;%......%&amp;gt;” block.&lt;/li&gt;
&lt;li&gt;The Web Broker app serves the response.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
I developed a VCL standalone Web Broker application as a proof of concept (it could be an ISAPI dll as well). See it in action in the following video:&lt;/div&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/NMBn6BjNEW0" width="420"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
That application is just a prototype. I really believe that we could build a robust server side component to leverage enterprise Pascal Server Pages. I used Web Broker in this example, but we could also build &lt;a href="http://wiki.freepascal.org/FPC_and_Apache_Modules" rel="nofollow" target="_blank"&gt;Apache Modules with Free Pascal&lt;/a&gt;. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I am posting below the code of the TWebModule1 class, which is the core of the Web Broker app. The full source code and executable can be downloaded &lt;a href="http://sites.google.com/site/yanniel821024/PSP.zip" rel="nofollow" target="_blank"&gt;here&lt;/a&gt;. (the code was compiled with Delphi XE2). Note that the code is somewhat messy; this was taken directly from my sandbox. Ah, I copy-pasted (and adjusted) the Pascal Script routines from this example: &lt;a href="http://lawrencebarsanti.wordpress.com/2009/11/28/introduction-to-pascal-script/" rel="nofollow" target="_blank"&gt;Introduction to Pascal Script&lt;/a&gt;.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;unit WebModuleUnit1;&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses System.SysUtils, System.Classes, Web.HTTPApp,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RegularExpressions;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;type&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; TWebModule1 = class(TWebModule)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure WebModule1DefaultHandlerAction(Sender: TObject;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { Private declarations }&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { Public declarations }&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function LoadStrFromFile(aFilename: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function ProducePage(aContent: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function ExecPascalScript(const Match: TMatch): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function CompileScript(Script: AnsiString; out Bytecode, Messages: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function RunCompiledScript(Bytecode: AnsiString; out RuntimeErrors: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; WebModuleClass: TComponentClass = TWebModule1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //ScriptOutput is not thread safe.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //ScriptOutput is a global variable.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //We should avoid global variables.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //TODO: Find a better way to store the script output&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; uPSCompiler, uPSRuntime;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;{$R *.dfm}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Write(P1: Variant);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //This try...except is ugly.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //TODO: Use a conditional checking instead&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScriptOutput:= ScriptOutput + String(P1);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ScriptOutput:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure Writeln(P1: Variant);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Write(P1);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= ScriptOutput + '&amp;lt;/br&amp;gt;';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.LoadStrFromFile(aFilename: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if not FileExists(aFilename) then Exit;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; with TStringStream.Create do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoadFromFile(aFilename);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= DataString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.ProducePage(aContent: string): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RegEx: TRegEx;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; aContent:= StringReplace(aContent, #13#10, '', [rfReplaceAll]);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RegEx.Create('\&amp;lt;\%(.)*?\%\&amp;gt;');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= regex.Replace(aContent, ExecPascalScript);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.ExecPascalScript(const Match: TMatch): string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Messages,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; RuntimeErrors: AnsiString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ScriptOutput:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= Match.Value;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= StringReplace(PS, '&amp;lt;%', '', []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; PS:= StringReplace(PS, '%&amp;gt;', '', []);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; if CompileScript(PS, Bytecode, Messages) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if RunCompiledScript(Bytecode, RuntimeErrors) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= ScriptOutput;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function ExtendCompiler(Compiler: TPSPascalCompiler; const Name: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Result := True;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.AddDelphiFunction('procedure Writeln(P1: Variant);');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.AddDelphiFunction('procedure Write(P1: Variant);');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; except&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result := False; // will halt compilation&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.CompileScript(Script: AnsiString; out Bytecode, Messages: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler: TPSPascalCompiler;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; i: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Bytecode:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Messages:= '';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler:= TPSPascalCompiler.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Compiler.OnUses:= ExtendCompiler;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Compiler.Compile(Script) and Compiler.GetOutput(Bytecode);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i:= 0 to Compiler.MsgCount - 1 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if Length(Messages) = 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Messages:= Compiler.Msg[i].MessageToString&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Messages:= Messages + #13#10 + Compiler.Msg[i].MessageToString;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compiler.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure ExtendRuntime(Runtime: TPSExec; ClassImporter: TPSRuntimeClassImporter);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime.RegisterDelphiMethod(nil, @Writeln, 'Writeln', cdRegister);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime.RegisterDelphiMethod(nil, @Write, 'Write', cdRegister);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;function TWebModule1.RunCompiledScript(Bytecode: AnsiString; out RuntimeErrors: AnsiString): Boolean;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime: TPSExec;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ClassImporter: TPSRuntimeClassImporter;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Runtime:= TPSExec.Create;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; ClassImporter:= TPSRuntimeClassImporter.CreateAndRegister(Runtime, false);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExtendRuntime(Runtime, ClassImporter);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Runtime.LoadData(Bytecode)&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and Runtime.RunScript&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and (Runtime.ExceptionCode = erNoError);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not Result then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RuntimeErrors:=&amp;nbsp; PSErrorToString(Runtime.LastEx, '');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClassImporter.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Runtime.Free;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLSource,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLPascalScriptEmbedded: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; //Set up HTMLSource at your convenience&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLSource:= GetCurrentDir + '\testPage.htm';&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; HTMLPascalScriptEmbedded:= LoadStrFromFile(HTMLSource);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; Response.Content:= ProducePage(HTMLPascalScriptEmbedded);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;end. &lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/4798569634632094914/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/12/pascal-server-pages-script.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4798569634632094914?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4798569634632094914?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/12/pascal-server-pages-script.html" title="Pascal Server Pages – Pascal Script" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/NMBn6BjNEW0/default.jpg" height="72" width="72" /><thr:total>7</thr:total></entry><entry gd:etag="W/&quot;CUcMQXczeip7ImA9WhNWF0Q.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-7571681773818168326</id><published>2011-12-02T23:41:00.009-05:00</published><updated>2012-12-17T20:11:20.982-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-17T20:11:20.982-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Salary Guide for Delphi developers: Let’s make it</title><content type="html">&lt;div style="text-align: justify;"&gt;
If you work as an IT professional in North America, you should probably find very useful the &lt;a href="http://s3.amazonaws.com/DBM/M3/2011/Downloads/RHT_SalaryGuide_2012.pdf" rel="nofollow" target="_blank"&gt;2012 Technology Salary Guide&lt;/a&gt; published by &lt;a href="http://www.roberthalftechnology.com/Employment-Resources" rel="nofollow" target="_blank"&gt;Robert Half Technology&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
This guide exposes the compensation trends (salary trends) for pretty much every position in Information Technology. It covers the United States of America and Canada, and you could even obtain salary ranges for particular cities.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
This guide is useful for both managers and non-managers individuals. In my particular case, I am always curious to know if I am getting paid decently.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
The tables below are an excerpt taken from the guide:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b&gt;&amp;nbsp;2012 Average Starting Salaries – United States&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;"&gt;&lt;tbody&gt;
&lt;tr style="mso-yfti-firstrow: yes; mso-yfti-irow: 0;"&gt;   &lt;td style="border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;Job Title&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;2011&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;2012&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;% Change&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1; mso-yfti-lastrow: yes;"&gt;   &lt;td style="border-top: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
Software Developer&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
$ 65,750 - $ 104,250 &lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
$ 70,000 - $ 111,000 &lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
6.5%&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;b&gt;2012 Average Starting Salaries – Canada&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;"&gt;&lt;tbody&gt;
&lt;tr style="mso-yfti-firstrow: yes; mso-yfti-irow: 0;"&gt;   &lt;td style="border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;Job Title&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;2011&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;2012&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-left: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-themecolor: text1; mso-border-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
&lt;b&gt;% Change&lt;/b&gt;&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1; mso-yfti-lastrow: yes;"&gt;   &lt;td style="border-top: none; border: solid black 1.0pt; mso-border-alt: solid black .5pt; mso-border-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
Software Developer&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
$ 56,250 - $ 94,000 &lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
$ 59,750 - $ 99,750&lt;/div&gt;
&lt;/td&gt;   &lt;td style="border-bottom: solid black 1.0pt; border-left: none; border-right: solid black 1.0pt; border-top: none; mso-border-alt: solid black .5pt; mso-border-bottom-themecolor: text1; mso-border-left-alt: solid black .5pt; mso-border-left-themecolor: text1; mso-border-right-themecolor: text1; mso-border-themecolor: text1; mso-border-top-alt: solid black .5pt; mso-border-top-themecolor: text1; padding: 0in 5.4pt 0in 5.4pt; width: 110.7pt;" valign="top" width="148"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;
6.2%&lt;/div&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
There are further statistics in the guide about Java, .NET, C++, PHP and other programming languages. You can use that info in order to tune the indicators above even more. There are no details about Delphi in this guide.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I think that we (the Delphi community) could gather some statistics about the salary rates for Delphi Developers. I propose running poll surveys to gather such information. Once the polls are closed, we will publish the outcomes and we can draft our conclusions.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The polls are finally closed.&lt;/b&gt; Go to the end of this post and take a look at the outcomes. Thanks a lot to all the participants: 45 in the United States and 30 in Canada. It’s funny how the number of voters was a multiple of 5 in both countries :-) &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;strike&gt;Take a look at the right column of this page: I have published two polls to collect the information about the salary rates in the United States and Canada. I am only putting together the data for these two countries, because I already have some reference data to compare with. (I am referring to the data in the tables above). It would be really nice if someone else could take ownership of similar polls for other countries.&lt;/strike&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;strike&gt;&lt;br /&gt;
&lt;/strike&gt;&lt;br /&gt;
&lt;strike&gt;&lt;b&gt;Important: &lt;/b&gt;&lt;/strike&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strike&gt;I will kindly ask to vote, IF and ONLY IF, you are (were) working as a Delphi Developer in the United States or Canada during the current year 2011. &lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;We could make this better if you enroll your coworkers or any other Delphi developers in your area.&lt;/strike&gt;&lt;/li&gt;
&lt;li&gt;&lt;strike&gt;The poll is by nature anonymous: we are just gathering collective information.&lt;/strike&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
&lt;strike&gt;&lt;b&gt;Please&lt;/b&gt;, in order for this to work we need your vote!&lt;/strike&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;What’s the salary for a Delphi Developer in the United States?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt; $ 50,000&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;   5&amp;nbsp; (11%)&lt;br /&gt;
$ 50,000 - $ 60,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  2&amp;nbsp; (4%)&lt;br /&gt;
&amp;gt; $ 60,000 - $ 65,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (2%)&lt;br /&gt;
&amp;gt; $ 65,000 - $ 75,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; 7&amp;nbsp; (15%)&lt;br /&gt;
&amp;gt; $ 75,000 - $ 85,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  12&amp;nbsp; (26%)&lt;br /&gt;
&amp;gt; $ 85,000 - $ 95,000&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;   4&amp;nbsp; (8%)&lt;br /&gt;
&amp;gt; $ 95,000 - $ 105,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; 5&amp;nbsp; (11%)&lt;br /&gt;
&amp;gt; $ 105,000 - $ 115,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   4&amp;nbsp; (8%)&lt;br /&gt;
&amp;gt; $ 115,000 &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;  5&amp;nbsp; (11%)&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;b&gt;What’s the salary for a Delphi Developer in Canada?&lt;/b&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;lt; $ 50,000 &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; 6&amp;nbsp; (20%)&lt;br /&gt;
$ 50,000 - $ 60,000&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;   5&amp;nbsp; (16%)&lt;br /&gt;
&amp;gt; $ 60,000 - $ 65,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  2&amp;nbsp; (6%)&lt;br /&gt;
&amp;gt; $ 65,000 - $ 75,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  3&amp;nbsp; (10%)&lt;br /&gt;
&amp;gt; $ 75,000 - $ 85,000&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; 2&amp;nbsp; (6%)&lt;br /&gt;
&amp;gt; $ 85,000 - $ 95,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (3%)&lt;br /&gt;
&amp;gt; $ 95,000 - $ 105,000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   5&amp;nbsp; (16%)&lt;br /&gt;
&amp;gt; $ 105,000 - $ 115,000 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;  1&amp;nbsp; (3%)&lt;br /&gt;
&amp;gt; $ 115,000 &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;  5&amp;nbsp; (16%)</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/7571681773818168326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/12/salary-guide-delphi-2012.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7571681773818168326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7571681773818168326?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/12/salary-guide-delphi-2012.html" title="Salary Guide for Delphi developers: Let’s make it" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU8ERnw9cCp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-9010127107085875819</id><published>2011-11-30T16:38:00.013-05:00</published><updated>2012-12-13T20:16:47.268-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:16:47.268-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pascal Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="recursive" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="recursion" /><category scheme="http://www.blogger.com/atom/ns#" term="iterative" /><category scheme="http://www.blogger.com/atom/ns#" term="Pascal" /><title>Generating Fibonacci numbers in Delphi: Recursive and iterative algorithms</title><content type="html">&lt;div style="text-align: justify;"&gt;
In this post, I want to implement a function that returns the Nth Fibonacci number. Initially, I will provide a recursive implementation that derives directly from the Fibonacci sequence definition. Afterwards, I will recode the same function using an iterative approach.&lt;br /&gt;
&lt;br /&gt;
Why do I want to do (share) such a thing? Well, firstly for fun :-) and secondly, because I was asked to do something similar in one phone screen interview. Really? Yep, I was asked to code a function to return the &lt;a href="http://www.yanniel.info/2011/04/factorial-delphi-recursive-iterative.html" target="_blank"&gt;factorial of a number&lt;/a&gt; and then, I had to read it over the phone. I implemented the recursive algorithm. At this point, I was asked why I decided to use recursion as opposed to iteration. My answer was that I find the recursive implementation easier (and cleaner) to write. The interviewer finally inquired me about the iterative implementation…&lt;br /&gt;
&lt;br /&gt;
This motivated me to resolve similar programming tasks (recursively and iteratively) just as a training exercise.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Well, enough with that blah, blah, blah. &lt;br /&gt;
&lt;br /&gt;
Taken from &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_numbers_in_popular_culture" rel="nofollow" target="_blank"&gt;Wikipedia&lt;/a&gt;: &lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The Fibonacci numbers form a sequence of integers, mathematically defined by&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; F(0)=0; F(1)=1; F(n) = F(n - 1) + F(n - 2) for n &amp;gt; 1.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;This results in the following sequence of numbers:&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...&lt;/i&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
This simply means that by definition the first Fibonacci number is 0, the second number is 1 and the rest of the Fibonacci numbers are calculated by adding the two previous numbers in the sequence.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Translating that into Delphi code:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; if aNumber &amp;lt; 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception.Create('The Fibonacci sequence is not defined for negative integers.');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; case aNumber of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; 0: Result:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; 1: Result:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= Fibonacci(aNumber - 1) + Fibonacci(aNumber - 2);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
The function above is the recursive implementation, which in my opinion fits naturally. Now, the iterative implementation might not be as cleaner as that: &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt; var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; I,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N_1,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N_2,&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; N: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; if aNumber &amp;lt; 0 then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; raise Exception.Create('The Fibonacci sequence is not defined for negative integers.');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; case aNumber of&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; 0: Result:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; 1: Result:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; else&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_1:= 0;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_2:= 1;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for I:=2 to aNumber do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N:= N_1 + N_2;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_1:= N_2;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N_2:= N;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= N;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
Finally, if you want to produce the first 21 Fibonacci numbers try this out:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;code&gt;program Project2;&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; {$APPTYPE CONSOLE}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; {$R *.res}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; uses&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; System.SysUtils;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; var&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; I: Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; function Fibonacci(aNumber: Integer): Integer;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; {Your implementation goes here}&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; begin&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; for I:=0 to 20 do&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Writeln(Fibonacci(I));&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; Readln;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; end.&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
Hopefully you are not bored to death :-)&lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/9010127107085875819/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/11/fibonacci-numbers-in-delphi.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/9010127107085875819?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/9010127107085875819?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/11/fibonacci-numbers-in-delphi.html" title="Generating Fibonacci numbers in Delphi: Recursive and iterative algorithms" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>6</thr:total></entry><entry gd:etag="W/&quot;DU8GQnw8fip7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-6674889585497223909</id><published>2011-11-25T18:34:00.008-05:00</published><updated>2012-12-13T20:17:03.276-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:17:03.276-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Internationalizing your Delphi application: An ABC example</title><content type="html">&lt;div style="text-align: justify;"&gt;
If you want to make your Delphi application general enough to address multiple locales, then you need to internationalize it. There are three common aspects that I want to emphasize (no necessarily in that order): &lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Resourcing &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Unit conversions&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dynamic messages&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
We’ll cover the three of them with a very simple example. Consider the following code snipped intended for the &lt;i&gt;en-US&lt;/i&gt; locale (English-United States of America):&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage('If the body temperature rises above 99°F the person is considered to have a fever.');&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;b&gt;Resourcing&lt;/b&gt; is the process of removing &lt;i&gt;hard-coded strings&lt;/i&gt; from the code by making them &lt;i&gt;resourcestrings &lt;/i&gt;instead.&lt;br /&gt;
&lt;br /&gt;
The code above is not localizable because the &lt;i&gt;ShowMessage &lt;/i&gt;procedure is taking a &lt;i&gt;hard-coded string&lt;/i&gt;. What do you do? Take a look:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
resourcestring&lt;br /&gt;
&amp;nbsp; strFeverDefinition = 'If the body temperature rises above 99°F the person is considered to have a fever.';&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(strFeverDefinition);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
We defined &lt;i&gt;strFeverDefinition &lt;/i&gt;as a &lt;i&gt;resourcestring &lt;/i&gt;and used it as a parameter for the &lt;i&gt;ShowMessage&lt;/i&gt; procedure. The functionality remains the same, but the function is now localizable. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Unit conversions&lt;/b&gt;: In some countries (like the United States and Belize) the temperature is given in the Fahrenheit scale, but in the rest is given in the Celsius scale. In order to internationalize this we can do the following:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
function GetFeverTemperature: string;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt;: LangID;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; //By default&lt;br /&gt;
&amp;nbsp; Result:= '37.2°C';&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; {read current system locale}&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt; := GetSystemDefaultLangID;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Assuming that only the United States and Belize use the Fahrenheit scale&lt;br /&gt;
&amp;nbsp; if (&lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt; = &lt;/code&gt;&lt;code&gt;{&lt;/code&gt;English - United States&lt;code&gt;}&lt;/code&gt; 1033&lt;code&gt;&lt;/code&gt;&lt;code&gt;) or&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/code&gt;&lt;code&gt;LangID&lt;/code&gt;&lt;code&gt; = &lt;/code&gt;{English - Belize} 10249&lt;code&gt;) then&lt;/code&gt;&lt;br /&gt;
&lt;code&gt; &amp;nbsp; Result:= '99°F';&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage('If the body temperature rises above ' + GetFeverTemperature + ' the person is considered to have a fever');&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Wait a minute, we managed the &lt;b&gt;unit conversion&lt;/b&gt; by introducing a &lt;b&gt;dynamic message&lt;/b&gt;, but we reintroduced the &lt;i&gt;hard-coded strings&lt;/i&gt;. That’s not good!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dynamic messages&lt;/b&gt;: We consider the &lt;i&gt;ShowMessage &lt;/i&gt;above to be a &lt;b&gt;dynamic message&lt;/b&gt;, because the parameter depends on the &lt;i&gt;GetFeverTemperature&lt;/i&gt; function, which of course can vary.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
To solve the pitfall above we can refactor the &lt;i&gt;DefineFever &lt;/i&gt;function as follows:&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
procedure TForm1.DefineFever;&lt;br /&gt;
resourcestring&lt;br /&gt;
&amp;nbsp; strFeverDefinition = 'If the body temperature rises above %0:s the person is considered to have a fever.';&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; ShowMessage(Format(strFeverDefinition, [GetFeverTemperature]));&lt;br /&gt;
end;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
We are just using a &lt;i&gt;format string&lt;/i&gt; (&lt;i&gt;resourcestring&lt;/i&gt;) that we can &lt;i&gt;format&lt;/i&gt; by using the &lt;i&gt;Format &lt;/i&gt;routine. This allows &lt;b&gt;resourcing&lt;/b&gt; and handling the &lt;b&gt;dynamic message&lt;/b&gt; all at once.&lt;br /&gt;
&lt;br /&gt;
The thing about &lt;b&gt;dynamic messages&lt;/b&gt; goes beyond. In Spanish, for instance, the &lt;b&gt;dynamic message&lt;/b&gt; would have been coded as follows:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
ShowMessage('Se considera que la persona tiene fiebre si la temperatura corporal es superior a ' + GetFeverTemperature);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Note that the &lt;i&gt;GetFeverTemperature&lt;/i&gt; is at the end of the &lt;i&gt;ShowMesssage&lt;/i&gt; parameter, as opposed to the English implementation that has it in the middle. There’s no way you can localize something like this if you don’t internationalize it first.&lt;br /&gt;
&lt;br /&gt;
So the ABC for Delphi localization is &lt;b&gt;Resourcing&lt;/b&gt;, &lt;b&gt;Unit Conversions&lt;/b&gt; and &lt;b&gt;Dynamic Messages&lt;/b&gt;.&amp;nbsp; &lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/6674889585497223909/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/11/internationalization-tips-delphi.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/6674889585497223909?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/6674889585497223909?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/11/internationalization-tips-delphi.html" title="Internationalizing your Delphi application: An ABC example" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DU8AR3oyfSp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-3293447750120825928</id><published>2011-11-21T18:34:00.006-05:00</published><updated>2012-12-13T20:17:26.495-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:17:26.495-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Creational Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Multiton Design Pattern in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
The &lt;i&gt;multiton &lt;/i&gt;is somewhat an extension of the &lt;i&gt;singleton &lt;/i&gt;pattern. It is referred as &lt;i&gt;registry of singletons&lt;/i&gt; by the &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" rel="nofollow" target="_blank"&gt;GOF&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;. I don’t know for sure who appointed the name &lt;i&gt;multiton&lt;/i&gt;: it’s an analogy derived from the term &lt;i&gt;singleton&lt;/i&gt;. So, &lt;b&gt;singleton &lt;/b&gt;= &lt;b&gt;single &lt;/b&gt;+ &lt;b&gt;ton&lt;/b&gt;; while &lt;b&gt;multiton &lt;/b&gt;= &lt;b&gt;multi &lt;/b&gt;+ &lt;b&gt;ton&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
The &lt;i&gt;singleton&lt;/i&gt; pattern guarantees that a class has only one instance; while the &lt;i&gt;multiton&lt;/i&gt; allows keeping multiple instances by maintaining a map of related keys and unique objects.&amp;nbsp; Note that there can be only one instance per key when implementing the &lt;i&gt;multiton&lt;/i&gt; pattern. Also, note that the key does not have to be a string value; it can be an object for example. Nonetheless, in our code sniped we will consider the key to be a string.&lt;br /&gt;
&lt;br /&gt;
I am going to tweak my &lt;a href="http://www.yanniel.info/2010/10/singleton-pattern-delphi.html" target="_blank" title="Implementing the Singleton Design Pattern in Delphi without Global Variables"&gt;singleton class implementation&lt;/a&gt; so that I can make it a &lt;i&gt;multiton&lt;/i&gt; instead:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
unit Multiton;&lt;br /&gt;
&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; Generics.Collections;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TMultiton = class&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Private fields and methods here...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class var _registry: TDictionary&amp;lt;string, TMultiton&amp;gt;;&lt;br /&gt;
&amp;nbsp; protected&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Create(aName: string): TMultiton;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class destructor Destroy;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; class function Lookup(aName: string): TMultiton;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //Other public methods and properties here...&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TMultiton }&lt;br /&gt;
&lt;br /&gt;
class function TMultiton.Create(aName: string): TMultiton;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if not Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry:= TDictionary&amp;lt;string, TMultiton&amp;gt;.Create;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if not _registry.TryGetValue(aName, Result) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= inherited Create as Self;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Add(aName, Result);&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class destructor TMultiton.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Values.ToArray[0].Free;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class function TMultiton.Lookup(aName: string): TMultiton;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.TryGetValue(aName, Result);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TMultiton.Destroy;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; _instance: TMultiton;&lt;br /&gt;
&amp;nbsp; ValuesArray: TArray&amp;lt;TMultiton&amp;gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; if Assigned(_registry) then&lt;br /&gt;
&amp;nbsp; begin&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ValuesArray:= _registry.Values.ToArray;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Clear;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry.Free;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; _registry:= nil;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for _instance in&amp;nbsp; ValuesArray do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if _instance &amp;lt;&amp;gt; Self then&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _instance.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; inherited;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
A few things I want you to note:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Instead of a single instance, we are holding a registry of instances. We do so by introducing the class variable &lt;i&gt;&lt;b&gt;_registry&lt;/b&gt;&lt;/i&gt; of type &lt;i&gt;&lt;b&gt;TDictionary&amp;lt;string, TMultiton&amp;gt;&lt;/b&gt;&lt;/i&gt;. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;We register (create) the different instances by calling the class function &lt;i&gt;&lt;b&gt;Create&lt;/b&gt;&lt;/i&gt;. This function gets the key name as a parameter. A new instance is only created if no matches to the key name are found in the dictionary. If a match is found, then the corresponding value is returned from the dictionary data structure.&lt;/li&gt;
&lt;li&gt;The &lt;i&gt;&lt;b&gt;Lookup &lt;/b&gt;&lt;/i&gt;class function allows retrieving a particular instance by giving its key name. Note that the &lt;i&gt;&lt;b&gt;Create &lt;/b&gt;&lt;/i&gt;function can also be used for this purpose, but it feels more natural to call &lt;i&gt;&lt;b&gt;Lookup &lt;/b&gt;&lt;/i&gt;for the searches, and &lt;i&gt;&lt;b&gt;Create &lt;/b&gt;&lt;/i&gt;for the registration (creation) of instances.&lt;/li&gt;
&lt;li&gt;We have provided a regular destructor that once invoked releases all the memory: not only the current &lt;i&gt;multiton&lt;/i&gt; instance, but the whole registry.&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/li&gt;
&lt;li&gt;We have also provided a class destructor in case that we forget to manually release the memory. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
This code was compiled with Delphi XE2, but it should also work for all versions above Delphi 2009. Comments, corrections and suggestions are most welcome.&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Consider reading these books about design patterns if you haven’t yet:&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Design Patterns: Elements of Reusable Object-Oriented Software" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0201633612&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Head First Design Patterns" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0596007124&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0596007124" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/Object-Models-Strategies-Patterns-Applications/dp/0138401179?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Object Models: Strategies, Patterns, and Applications (2nd Edition)" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0138401179&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0138401179" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/3293447750120825928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/11/multiton-design-pattern-delphi.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3293447750120825928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/3293447750120825928?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/11/multiton-design-pattern-delphi.html" title="Multiton Design Pattern in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DU8DQng-fip7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-9091275202019482691</id><published>2011-11-03T11:18:00.015-04:00</published><updated>2012-12-13T20:17:53.656-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:17:53.656-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Dependency Injection in Delphi: a simple example</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I want to give a fairly simple Delphi example that will expose the dependency injection pattern. No framework, no third-party library will be needed here: just plain Delphi code.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I won’t dig into the&lt;a href="http://martinfowler.com/articles/injection.html" rel="nofollow" target="_blank" title="Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern"&gt; different forms of dependency injection&lt;/a&gt;. I will explain the idea of the pattern as simple as possible.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Instead of giving you bunch of definitions, I will present you with some code. The need to inject a dependency will come naturally. You’ll see:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; IDependency = interface&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; ['{618030A2-DB17-4532-81D0-D5AA6F73DC66}']&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; TDependencyA = class(TInterfacedObject, IDependency)&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; TDependencyB = class(TInterfacedObject, IDependency)&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;TConsumer = class&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency: IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aDependencyClassName: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{ TDependencyA }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;procedure TDependencyA.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; WriteLn('Instance of type TDependencyA');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{ TDependencyB }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;procedure TDependencyB.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; WriteLn('Instance of type TDependencyB');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{ TConsumer }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;constructor TConsumer.Create(aDependencyClassName: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; if aDependencyClassName = 'TDependencyA'&amp;nbsp; then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency:= TDependencyA.Create&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; else if aDependencyClassName = 'TDependencyB'&amp;nbsp; then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency:= TDependencyB.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;procedure TConsumer.GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; if FDependency &amp;lt;&amp;gt; nil then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FDependency.GetType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
It is a good and recommended practice in OOP to decrease coupling as much as possible. This means that each component (class) should avoid knowing implementation details of the other components (classes).&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
In our example, the &lt;i&gt;TConsumer&lt;/i&gt; class has a dependency of type &lt;i&gt;IDependency&lt;/i&gt;. So far so good, since we are abstracting any implementation specifics by using an interface (contract). The problem becomes obvious when you take a look at the constructor of &lt;i&gt;TConsumer&lt;/i&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;i&gt;TConsumer.Create&lt;/i&gt; is instantiating the concrete classes &lt;i&gt;TDependencyA&lt;/i&gt;&amp;nbsp;&amp;nbsp; or &lt;i&gt;TDependencyB &lt;/i&gt;depending on the string parameter &lt;i&gt;aDependencyClassName&lt;/i&gt;. As you can see, the design is not well decupled here, because the consumer class (&lt;i&gt;TConsumer&lt;/i&gt;) is hard-coding implementation details about its dependency.&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The question is: can we decuple this design even more? Yes, the dependency injection pattern will do it for us.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
It’s now time to refactor our code a little bit. We’ll start by changing the signature of the constructor of the &lt;i&gt;TConsumer &lt;/i&gt;class:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;constructor TConsumer.Create(aDependency: IDependency);&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; FDependency:= aDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Instead of choosing the concrete dependency to instantiate within the constructor, we are now injecting the dependency trough the aDependency parameter. Now the class &lt;i&gt;TConsumer&lt;/i&gt; is completely independent of the dependency concrete class.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Ok, ok, but we still need to create the concrete dependency instance somewhere, right? Yes, we do. For that we will create a new class &lt;i&gt;TDependencyInjector &lt;/i&gt;whose only purpose is to return the right dependency instance. This class will use reflection in order to create the right instance of &lt;i&gt;IDependency&lt;/i&gt;. It will use just a string parameter that contains the dependency class name. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; RTTI,&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; Dependencies;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; TDependencyInjector =&amp;nbsp; class&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class function GetDependency(aDependencyClassName: string): IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{ TDependencyInjector }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;class function TDependencyInjector.GetDependency(aDependencyClassName: string): IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; RttiContext: TRttiContext;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; RttiType: TRttiInstanceType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; RttiType := RttiContext.FindType(aDependencyClassName) as TRttiInstanceType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; if RttiType &amp;lt;&amp;gt; nil then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Result:= RttiType.GetMethod('Create').Invoke(RttiType.MetaclassType, []).AsInterface as IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Finally, let's put all the pieces together. Consider this console application that puts all the pieces in place:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;program DependencyInjection;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{$APPTYPE CONSOLE}&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;{$R *.res}&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;...&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeConsumerObj: TConsumer;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; Dependency: IDependency;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; Dependency:= TDependencyInjector.GetDependency('Dependencies.TDependencyA');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //Dependency:= TDependencyInjector.GetDependency('Dependencies.TDependencyB');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeConsumerObj:= TConsumer.Create(Dependency);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeConsumerObj.GetDependencyType;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeConsumerObj.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
In the code above we get the &lt;i&gt;Dependency &lt;/i&gt;instance at runtime by using the &lt;i&gt;TDependencyInjector &lt;/i&gt;class. Then we inject that dependency using the constructor of the class&amp;nbsp; &lt;i&gt;TConsumer&lt;/i&gt;. We have got a more decoupled design by using dependency injection. Don't you agree? ;-)&lt;br /&gt;
&lt;br /&gt;
Get the full source code of this example &lt;a href="http://sites.google.com/site/yanniel821024/DependencyInjection.rar" rel="nofollow" target="_blank"&gt;here&lt;/a&gt; (written in Delphi XE 2).&lt;/div&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/9091275202019482691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/11/dependency-injection-in-delphi.html#comment-form" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/9091275202019482691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/9091275202019482691?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/11/dependency-injection-in-delphi.html" title="Dependency Injection in Delphi: a simple example" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>12</thr:total></entry><entry gd:etag="W/&quot;DEAMQXsyeCp7ImA9WhBXF0s.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-7059420152204430220</id><published>2011-10-18T22:44:00.061-04:00</published><updated>2013-03-31T17:53:00.590-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-31T17:53:00.590-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Canada" /><category scheme="http://www.blogger.com/atom/ns#" term="tips for immigrants" /><category scheme="http://www.blogger.com/atom/ns#" term="nonimmigrant visas" /><category scheme="http://www.blogger.com/atom/ns#" term="visitor visas" /><category scheme="http://www.blogger.com/atom/ns#" term="US" /><category scheme="http://www.blogger.com/atom/ns#" term="VISA" /><title>US Visitor Visa for Permanent Residents of Canada: How to apply online?</title><content type="html">&lt;div style="text-align: justify;"&gt;
I came to Canada as a federal skilled worker 20 months ago (February 26th, 2010). Since the day I landed I am a Permanent Resident of Canada. I have always wanted to visit the United States of America: so I decided to go for it.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Canadian Citizens do not need a &lt;i&gt;visa &lt;/i&gt;to enter the US. In contrast, if you are a permanent resident of Canada (not citizen yet) you might need a &lt;i&gt;visa &lt;/i&gt;to enter American soil. I believe the need for a &lt;i&gt;visa &lt;/i&gt;relies on the nationality or citizenship you hold. In any case, I am Cuban and Cubans need a &lt;i&gt;visa&lt;/i&gt;. If you, like me, need a visitor visa to enter the States from Canada, this is the ABC…&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;i&gt;Visitor Visas&lt;/i&gt; allow you to enter the US temporarily: that’s why they are called &lt;i&gt;nonimmigrant visas&lt;/i&gt;. These &lt;i&gt;visas &lt;/i&gt;come in two flavors:&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Business Visitor Visas (B-1)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pleasure, Tourism, Medical Treatment - Visitor Visas (B-2)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
In my case, I applied for a &lt;i&gt;B-2 visa&lt;/i&gt;, since the purpose of my visit to the US is mainly recreational.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b&gt;Step 1:&lt;/b&gt; You need to fill an &lt;i&gt;Online Nonimmigrant Visa Electronic Application, Form DS-160&lt;/i&gt;. Don’t get scared for the name. You simply go to &lt;a href="https://ceac.state.gov/genniv/" rel="nofollow" target="_blank"&gt;this website&lt;/a&gt; and fill in the information required as you go. There is a lot of information that you need to provide.&amp;nbsp; If you need to stop one day, then you can resume the filling process at the next day.&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote style="color: red;"&gt;
In this step you will be asked to upload a recent digital picture(s) of the applicant(s). There are specifications for the pictures somewhere on the Internet, but I didn’t bother to find them. I just went to the nearest &lt;a href="http://www.blacks.ca/" rel="nofollow" target="_blank"&gt;Black’s&lt;/a&gt; facility and told them that I needed a &lt;i&gt;US Visitor Visa &lt;/i&gt;picture.&amp;nbsp; They know the specifications, since they are a professional photo service. At the end, they shot the picture and burned it into a CD for me (all this in 15 minutes). The cost (tax included) was $22.59 CAD.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
When you complete your application you will be presented a confirmation page. You have to print that confirmation page and present it at the time of the interview. The confirmation page contains a bar code that should be legible; so make sure you have a good printer at hand.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="color: red; text-align: center;"&gt;
Important: you need to complete step 1 before proceeding to step 2.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;b&gt;Step 2: &lt;/b&gt;You need to pay a fee for your &lt;i&gt;visa &lt;/i&gt;application and then you have to schedule an appointment for your &lt;i&gt;visa &lt;/i&gt;interview.&amp;nbsp; The fee for a &lt;i&gt;B-2 visa&lt;/i&gt; is $160 USD (it was $140 USD prior to Friday, April 13, 2012, but not anymore). To fulfill this step you need to login (register) at this website: &lt;a href="http://usvisa-info.com/en-CA/selfservice/login" rel="nofollow" target="_blank"&gt;http://usvisa-info.com/en-CA/selfservice/login&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Once longed into your account you will need to provide some basic information and then, you should be able to pay your &lt;i&gt;visa fee&lt;/i&gt; online (Paypal, Credit Card) and schedule the interview (you have to choose date, time and place). It is not mandatory to pay online; for a full list of fee payment options consult this URL: &lt;a href="http://usvisa-info.com/en-CA/selfservice/us_fee_payment_options" rel="nofollow" target="_blank"&gt;http://usvisa-info.com/en-CA/selfservice/us_fee_payment_options&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
You will be asked to print a receipt after you have completed the fee payment. Make sure you print this receipt, since you will have to present it at the time of the interview.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
When you complete step 2, the website will give you the option to print a summary of the interview scheduling. Print it, since I was asked for it the day of the interview.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
What do you need to bring the day of the interview?&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;ul&gt;
&lt;li&gt;A passport valid for at least 6 month beyond the applicant's intended period of stay in the US.&lt;/li&gt;
&lt;li&gt;Your Canadian Permanent Resident card.&lt;/li&gt;
&lt;li&gt;The confirmation page with the bar code (step 1).&lt;/li&gt;
&lt;li&gt;The receipt of your &lt;i&gt;visa fee&lt;/i&gt; payment (step 2).&lt;/li&gt;
&lt;li&gt;The summary of the interview scheduling (step 2).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;All the documents you think might support your case (in my case I gathered my work contract, bank statements, payroll stats, tax notice of assessment)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Take a look at the existing comments: there’s a lot of useful information in there that complements what I have written in the body of this post.&lt;br /&gt;
&lt;br /&gt;
Please, note that I am a regular person, not an immigration or legal advisor. I am only posting here the facts about my own experience. &amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
If you think this article is useful; would you mind recommending it by clicking the &lt;b&gt;&lt;span style="color: orange;"&gt;Google Plus (G+)&amp;nbsp;&lt;/span&gt; &lt;/b&gt;button at the beginning of the post? Thanks! &lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/7059420152204430220/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/10/us-visitor-visa-for-canadian-residents.html#comment-form" title="175 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7059420152204430220?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7059420152204430220?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/10/us-visitor-visa-for-canadian-residents.html" title="US Visitor Visa for Permanent Residents of Canada: How to apply online?" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>175</thr:total></entry><entry gd:etag="W/&quot;DU8NSXw9fCp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-7893425994171877967</id><published>2011-09-22T12:25:00.023-04:00</published><updated>2012-12-13T20:18:18.264-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:18:18.264-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Computers" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Structural patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Decorator Design Pattern in Delphi. Multiple Decorations</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
In my &lt;a href="http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html" title="Decorator Pattern in Delphi. Single decoration"&gt;previous post&lt;/a&gt; I introduced the decorator design pattern to you. I used a fairly simple example (a silly example if you wish) in order to give you a flavour of the pattern. I wrote Delphi code for that matter and I focused in having ONE, and only ONE, decorator class.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
This was the situation in the original example: we implemented a &lt;b&gt;TConsole&lt;/b&gt; class with a &lt;i&gt;Write &lt;/i&gt;method that writes a text to the standard output. Then, we used a &lt;b&gt;TUpperCaseConsole&lt;/b&gt; class to decorate a &lt;b&gt;TConsole&lt;/b&gt; object. The decoration itself was simple: uppercasing the text to be shown.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Now I want to add a second decoration, which is &lt;i&gt;framing &lt;/i&gt;the text to be shown within a rectangle of asterisks (*). For that I will create a new decorator class: &lt;b&gt;TFramedConsole&lt;/b&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Let’s present a raw piece of code: (We will refine and refactor the code later)&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write('Hello World!');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end.&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
In the code above we added a second decoration. The output for that code should be something like this: &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**&amp;nbsp;&amp;nbsp; HELLO WORLD!&amp;nbsp;&amp;nbsp; **&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b&gt;This is cool:&lt;/b&gt; We can even add the same decoration several times. For example, to provide a double frame we would do something like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //third decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write('Hello World!');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Can you guess the output now? It’s like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**&amp;nbsp;&amp;nbsp; HELLO WORLD!&amp;nbsp;&amp;nbsp; **&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;**********************&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
How are the decorated and decorator classes put together when multiple decorations are needed? There are two key things to remember:&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;The different concrete decorators (&lt;b&gt;TUpperCaseConsole&lt;/b&gt; and &lt;b&gt;TFramedConsole&lt;/b&gt;) must inherit from a base decorator class. We will introduce the &lt;b&gt;TDecoratedConsole &lt;/b&gt;class as the common ancestor for our decorators. &lt;/li&gt;
&lt;li&gt;The base decorator class forwards the calls to its &lt;i&gt;Write &lt;/i&gt;method to the decorated object’s &lt;i&gt;Write&lt;/i&gt; method. &lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The code looks like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; SysUtils, Windows;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TConsole = class&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); virtual;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TDecoratedConsole = class(TConsole)  //Base Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TUpperCaseConsole = class(TDecoratedConsole) //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TFramedConsole = class(TDecoratedConsole)    //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FText:= aText;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; Writeln(FText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TDecoratedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;constructor TDecoratedConsole.Create(aConsole: TConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole:= aConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;destructor TDecoratedConsole.Destroy;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TDecoratedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole.Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TUpperCaseConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TUpperCaseConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; aText:= UpperCase(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TFramedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TFramedConsole.CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TextLength: Integer;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; RealText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; if Pos('*', aText) = 0 then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText:= '**   ' +  aText + '   **';&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; RealText:= Trim(StringReplace(aText, '*', '', [rfReplaceAll]));&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TextLength:= Length(RealText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine:= StringOfChar('*', TextLength + 10);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; aText:= AsteriskLine    + #13#10 +&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText        + #13#10 + AsteriskLine;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TFramedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; CreateFrame(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
I know you are dying to say: &lt;i&gt;the code above is awful because the decorators are bounded to a specific implementation of the decorated class&lt;/i&gt;. Indeed, we are going to fix that by introducing a &lt;b&gt;TAbstractConsole &lt;/b&gt;class, which will be the common ancestor of the decorated and decorator classes.  The &lt;b&gt;TAbstractConsole &lt;/b&gt;class is &lt;i&gt;abstract&lt;/i&gt;, meaning it has no implementation. You could have used an &lt;i&gt;Interface &lt;/i&gt;type instated, something like &lt;b&gt;IAbstractConsole&lt;/b&gt;. I’ll leave that to you.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Finally, I present you the consuming code plus the class definition code:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;code&gt;//Consuming code&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole: TAbstractConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TConsole.Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole); //first decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //second decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; MyConsole:= TFramedConsole.Create(MyConsole); //third decoration&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write('Hello World!');&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; Readln;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;//Class definition code&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;interface&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;uses&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; SysUtils, Windows;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;type&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TAbstractConsole = class           //Abstract class ==&amp;gt; Interface&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string);  virtual; abstract;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TConsole = class(TAbstractConsole) //Concrete class&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TDecoratedConsole = class(TAbstractConsole)  //Base Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TAbstractConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TAbstractConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TUpperCaseConsole = class(TDecoratedConsole) //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TFramedConsole = class(TDecoratedConsole)    //Concrete Decorator&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; private&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;implementation&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FText:= aText;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; Writeln(FText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TDecoratedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;constructor TDecoratedConsole.Create(aConsole: TAbstractConsole);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Create;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole:= aConsole;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;destructor TDecoratedConsole.Destroy;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TDecoratedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; FConsole.Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TUpperCaseConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TUpperCaseConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; aText:= UpperCase(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;{ TFramedConsole }&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TFramedConsole.CreateFrame(var aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TextLength: Integer;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; RealText: string;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; if Pos('*', aText) = 0 then&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText:= '**   ' +  aText + '   **';&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; RealText:= Trim(StringReplace(aText, '*', '', [rfReplaceAll]));&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; TextLength:= Length(RealText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; AsteriskLine:= StringOfChar('*', TextLength + 10);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; aText:= AsteriskLine    + #13#10 +&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aText        + #13#10 + AsteriskLine;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;procedure TFramedConsole.Write(aText: string);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; CreateFrame(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&amp;nbsp; inherited Write(aText);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I hope this was useful and I am definitely waiting for you feedback. Corrections and suggestions are welcome in the comment section below. Thanks!&lt;br /&gt;
&lt;br /&gt;
For further reading about design patterns get your hands on these classics:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="font-family: inherit;"&gt;
&lt;span style="font-size: 12pt;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Design Patterns: Elements of Reusable Object-Oriented Software" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0201633612&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Head First Design Patterns" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0596007124&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0596007124" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/Object-Models-Strategies-Patterns-Applications/dp/0138401179?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Object Models: Strategies, Patterns, and Applications (2nd Edition)" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0138401179&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0138401179" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/7893425994171877967/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7893425994171877967?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/7893425994171877967?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html" title="Decorator Design Pattern in Delphi. Multiple Decorations" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU4FRH88cCp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-75425698973535468</id><published>2011-08-26T12:48:00.017-04:00</published><updated>2012-12-13T20:18:35.178-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:18:35.178-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Computers" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Structural patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Decorator Design Pattern in Delphi. Single decoration</title><content type="html">&lt;div style="text-align: justify;"&gt;
Decorator (also referred as Wrapper) is classified by &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" rel="nofollow" target="_blank"&gt;GoF&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt; &lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;as a structural pattern. Its purpose is to:&lt;br /&gt;
&lt;br /&gt;
“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.”&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Both inheritance and the decorator pattern aim towards extending the functionality. This is what they have in common. &lt;br /&gt;
&lt;br /&gt;
There are a couple of remarkable differences:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Inheritance extends the functionality at compilation time (statically). The decorator pattern extends the functionality at runtime (dynamically).&lt;/li&gt;
&lt;li&gt;Inheritance extends the functionality of a whole class (all objects of the extended class get the extended functionality). The decorator pattern allows extending the functionality of a selected object (or group of objects) without affecting the remaining objects.&amp;nbsp;&amp;nbsp; &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
You can think of the decorator pattern as a way to add make-up to an object or even as a way to attach accessories to that object. All this is done on the fly after the object itself has been created.&lt;br /&gt;
&lt;br /&gt;
Let’s walk through a simple task to get the idea. This example might sound silly. I want it silly so that you can focus on the decorator implementation, avoiding any extra complexity.&lt;br /&gt;
&lt;br /&gt;
Please, be aware that this design is somewhat unfinished, since we are only covering the case for a single decoration (just one functionality to be extended). In real life, we will need multiple decorators in order to add multiple responsibilities. As this is a controlled example (just for the purpose of this discussion), I am enforcing that only ONE responsibility is going to be extended. This means, we will have ONE decorator class. Because of that, I have made some &lt;i&gt;simplifications &lt;/i&gt;to the design; so that you get a &lt;i&gt;taste &lt;/i&gt;of the decorator pattern in its simplest expression.&lt;br /&gt;
&lt;br /&gt;
Later on, in &lt;a href="http://www.yanniel.info/2011/09/decorator-design-pattern-in-delphi.html" title="Decorator Pattern in Delphi. Multiple Decorations"&gt;other post&lt;/a&gt;, we’ll see how to add multiple responsibilities (with multiple decorator classes). For that, we’ll need a more complex design to overcome the shortcomings of this initial example. For now, just get the idea...we'll come back later to the multiple decorations scenario.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;i&gt;If you get some time, take a look at the discussion in the comments section.&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 1: &lt;/b&gt;Let’s create a &lt;i&gt;TConsole&lt;/i&gt; class which purpose is to output a given text to the standard output. The code might be something like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
interface&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TConsole = class&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string);&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
procedure TConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Writeln(aText);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;b&gt;Subtask 2:&lt;/b&gt; Let’s use the &lt;i&gt;TConsole&lt;/i&gt; class to printout “Hello World!”. The following code snipped does it:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MyConsole: TConsole; &lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; MyConsole:= TConsole.Create;&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write('Hello World!');&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
This is how the output looks like:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;span style="background-color: black; color: white;"&gt;Hello World!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 3:&lt;/b&gt; Now, let’s decorate the object referenced by &lt;i&gt;MyConsole &lt;/i&gt;(only that object, not the whole class). What I want is to upper case every text to be printed out. We need to define a decorator class &lt;i&gt;TUpperCaseConsole&lt;/i&gt; for that purpose. See the code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
interface&lt;br /&gt;
&lt;br /&gt;
uses&lt;br /&gt;
&amp;nbsp; SysUtils;&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TConsole = class&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); virtual;&lt;br /&gt;
&amp;nbsp; end;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp; //Decorator &lt;br /&gt;
&amp;nbsp; TUpperCaseConsole = class(TConsole)&lt;br /&gt;
&amp;nbsp; private&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; FConsole: TConsole;&lt;br /&gt;
&amp;nbsp; public&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; constructor Create(aConsole: TConsole);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; destructor Destroy; override;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; procedure Write(aText: string); override;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br /&gt;
implementation&lt;br /&gt;
&lt;br /&gt;
{ TConsole }&lt;br /&gt;
&lt;br /&gt;
procedure TConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; Writeln(aText);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
{ TUpperCaseConsole }&lt;br /&gt;
&lt;br /&gt;
constructor TUpperCaseConsole.Create(aConsole: TConsole);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; inherited Create;&lt;br /&gt;
&amp;nbsp; FConsole:= aConsole;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
destructor TUpperCaseConsole.Destroy;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; FConsole.Free;&lt;br /&gt;
&amp;nbsp; inherited;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TUpperCaseConsole.Write(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; aText:= UpperCase(aText);&lt;br /&gt;
&amp;nbsp; &lt;/code&gt;&lt;code&gt;FConsole.&lt;/code&gt;&lt;code&gt;Write(aText);&lt;br /&gt;
end; &lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Notice in the code above that the decorator class (&lt;i&gt;TUpperCaseConsole&lt;/i&gt;) inherits from the decorated class (&lt;i&gt;TConsole&lt;/i&gt;). This makes both the decorated and the decorator objects to share the same public interface. Furthermore, the &lt;i&gt;TUpperCaseConsole &lt;/i&gt;class &lt;i&gt;Has-A&lt;/i&gt; field of the &lt;i&gt;TConsole&lt;/i&gt; type. We’ll use this field to forward the printing functionality to the &lt;i&gt;TConsole&lt;/i&gt; class, once we have applied the cosmetic (upper case transformation) to the text.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subtask 4:&lt;/b&gt; Let’s now create some consuming code to decorate one &lt;i&gt;TConsole&lt;/i&gt; object on the fly. Note how the &lt;i&gt;TUpperCaseConsole &lt;/i&gt;constructor wraps (decorates) the object referenced by &lt;i&gt;MyConsole&lt;/i&gt;.&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; MyConsole: TConsole;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; MyConsole:= TConsole.Create;&lt;br /&gt;
&amp;nbsp; MyConsole:= TUpperCaseConsole.Create(MyConsole);&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Write('Hello World!');&lt;br /&gt;
&amp;nbsp; finally&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; MyConsole.Free;&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
This is how the output looks like after the decorator has been applied:&lt;span style="background-color: black; color: white;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="background-color: black; color: white;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="background-color: black; color: white;"&gt;HELLO WORLD!&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
In real life, you’ll have to judge whether the decorator pattern is the best alternative to be applied to solve a particular problem. Not always it the right way to go with. For more details get your hands on these classics books.&lt;/div&gt;
&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Design Patterns: Elements of Reusable Object-Oriented Software" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0201633612&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201633612" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Head First Design Patterns" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0596007124&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0596007124" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.amazon.com/Object-Models-Strategies-Patterns-Applications/dp/0138401179?ie=UTF8&amp;amp;tag=lmaoookaiie-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969" imageanchor="1" rel="nofollow" target="_blank"&gt;&lt;img alt="Object Models: Strategies, Patterns, and Applications (2nd Edition)" src="http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0138401179&amp;amp;tag=lmaoookaiie-20" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=lmaoookaiie-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0138401179" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/75425698973535468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html#comment-form" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/75425698973535468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/75425698973535468?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/08/decorator-pattern-delphi-single.html" title="Decorator Design Pattern in Delphi. Single decoration" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>16</thr:total></entry><entry gd:etag="W/&quot;DU4HRnc8fip7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-5385986656053172403</id><published>2011-08-19T13:25:00.013-04:00</published><updated>2012-12-13T20:18:57.976-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:18:57.976-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Computers" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Anonymous Methods in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
Under the scope of Delphi, an &lt;b&gt;anonymous method&lt;/b&gt; is either a &lt;i&gt;procedure &lt;/i&gt;or &lt;i&gt;function &lt;/i&gt;that’s unattached to an identifier. In other words, &lt;a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html" rel="nofollow" target="_blank"&gt;anonymous methods&lt;/a&gt; don’t have names, which is why they are called “anonymous”.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Basically, you can assign a block of code (in the form of a &lt;i&gt;procedure &lt;/i&gt;or &lt;i&gt;function&lt;/i&gt;) directly to a variable.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I am going to give you a simplistic example. I am going to &lt;i&gt;Keep it simple, Stupid!&lt;/i&gt; to avoid distracting you with any complexity. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
This is the wording of the task: create a console application which prints “Hello world” and “Good bye” to the standard output. Constraint: use the &lt;i&gt;Writeln &lt;/i&gt;function just once in the code.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
To accomplish such reckless task in the old days (before the introduction of &lt;b&gt;anonymous methods&lt;/b&gt;) you could do this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
program Project1;&lt;br /&gt;
&lt;br /&gt;
{$APPTYPE CONSOLE}&lt;br /&gt;
&lt;br /&gt;
procedure PrintString(aText: string);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp;Writeln(aText);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; PrintString('Hello world');&lt;br /&gt;
&amp;nbsp; PrintString('Good bye');&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
How to do the same with &lt;b&gt;anonymous methods&lt;/b&gt;? Take a look at the following code:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
program Project1;&lt;br /&gt;
&lt;br /&gt;
{$APPTYPE CONSOLE}&lt;br /&gt;
&lt;br /&gt;
type&lt;br /&gt;
&amp;nbsp; TMyAnonymousProcedureType = reference to procedure(aText: string);&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; A: TMyAnonymousProcedureType;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; A:= procedure(aText: string) //No semicolon here&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; begin&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; Writeln(aText);&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; end;&lt;br /&gt;
&amp;nbsp; A('Hello world');&lt;br /&gt;
&amp;nbsp; A('Good bye');&lt;br /&gt;
&amp;nbsp; Readln;&lt;br /&gt;
end.&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
As you can see in the example above, we have assigned code directly to the variable &lt;i&gt;A&lt;/i&gt;. Then, we called &lt;i&gt;A&lt;/i&gt; with parameters, and Voilà!: we have accomplished our reckless task with &lt;b&gt;anonymous methods&lt;/b&gt; as well.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Pay attention to this:&amp;nbsp; if you are tented to declare variable &lt;i&gt;A&lt;/i&gt; like this:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; A: reference to procedure(aText: string);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Don’t! That shortcut doesn’t work. You’ll get a compilation error…like this:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Undeclared identifier: ‘reference’&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
So, you do need to declare:&lt;/div&gt;
&lt;code&gt;&lt;br /&gt;
type&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; TMyAnonymousProcedureType = reference to procedure(aText: string);&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Only later you can define the type of variable &lt;i&gt;A&lt;/i&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
You might be asking by now: why to bother with all this? What's the benefit&lt;b&gt;&lt;/b&gt;? Well, in the previous example there’s little or none benefit present.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Generally speaking, &lt;b&gt;anonymous methods&lt;/b&gt; are handy in the following cases:&lt;/div&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;You have been trying to name a local method for hours. You cannot think of a name for it. Well, think no more: use &lt;b&gt;anonymous methods&lt;/b&gt;. Don’t put a tasteless name like &lt;i&gt;Foo()&lt;/i&gt;, &lt;i&gt;XXX()&lt;/i&gt;, &lt;i&gt;Aux&lt;/i&gt;(), etc.&lt;/li&gt;
&lt;li&gt;You create a function that is called just once(it’s just called from one spot).&lt;/li&gt;
&lt;li&gt;You can use &lt;b&gt;anonymous methods&lt;/b&gt; to provide elegant and simpler implementations. This is the case when combining &lt;b&gt;generics types&lt;/b&gt; with &lt;b&gt;anonymous methods&lt;/b&gt; for example. I should write about this shortly. Subscribe to my feed and stay tuned :-)&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
With this post I wanted to introduce &lt;b&gt;anonymous methods&lt;/b&gt; to you. It’s OK if you don’t see the benefits clearly right now. You’ll get there :-)&lt;/div&gt;
&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/5385986656053172403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/08/anonymous-methods-in-delphi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/5385986656053172403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/5385986656053172403?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/08/anonymous-methods-in-delphi.html" title="Anonymous Methods in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU4BRnY9fCp7ImA9WhNWFEk.&quot;"><id>tag:blogger.com,1999:blog-3701737190756431503.post-4390956600548964998</id><published>2011-08-15T12:11:00.010-04:00</published><updated>2012-12-13T20:19:17.864-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-13T20:19:17.864-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Delphi Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Delphi" /><category scheme="http://www.blogger.com/atom/ns#" term="Computers" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object-Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Pascal Programming" /><title>Hide the utter "Create" constructor of TObject in Delphi</title><content type="html">&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
In Delphi, constructors can be inherited; this doesn’t happen in Java, C# and C++ for example. Furthermore, constructors in Delphi can have multiple and different names; usually they are called &lt;b&gt;Create&lt;/b&gt;, but this is just a convention, since you can define a constructor with whatever name you choose.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
In addition to all this, all classes in Delphi inherit ultimately from &lt;b&gt;TObject&lt;/b&gt;, which contains a &lt;i&gt;public&lt;/i&gt; parameterless constructor, named &lt;b&gt;Create&lt;/b&gt;.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Due to the facts above, it‘s easy to understand that all classes in Delphi have a &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor, that has been inherited from &lt;b&gt;TObject&lt;/b&gt;. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I am not going to discuss here whether this is bad or good. What I want to show you is a way to hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; in case you need to do so.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;b style="color: red;"&gt;Burn this out&lt;/b&gt;: you cannot hide any member (field, method, constructor, destructor) in Delphi by decreasing the level of visibility. If a member in a superclass is &lt;i&gt;public&lt;/i&gt;, you cannot hide it in a child class by changing the visibility to &lt;i&gt;protected&lt;/i&gt; or &lt;i&gt;private&lt;/i&gt;. Once &lt;i&gt;public&lt;/i&gt; you are always &lt;i&gt;public&lt;/i&gt;. This means, you cannot hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; by lowering its visibility in an inheriting class. &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
So, how can we hide the &lt;b&gt;Create &lt;/b&gt;constructor of &lt;b&gt;TObject&lt;/b&gt;? Is there even a way for doing so? Yes, there is a way. We came to the solution in the LinkedIn’s  &lt;i&gt;Delphi Professionals&lt;/i&gt; group. I thought it would be worthy to share this with the rest of the Delphi community.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Basically, you can hide the &lt;i&gt;public&lt;/i&gt; &lt;b&gt;Create &lt;/b&gt;parameterless constructor of &lt;b&gt;TObject&lt;/b&gt; with another &lt;i&gt;public&lt;/i&gt; method having the same &lt;b&gt;Create &lt;/b&gt;name. For example:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;u&gt;Class definition snipped&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;//this constructor takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;constructor Create(aParameter1: string; aParameter2: Integer ); &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;u&gt;Consuming code snipped&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeObject: TSomeClass;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeObject:= TSomeClass.Create; //This does not compile!&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create('Hello People!', 12);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TODO&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeObject.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
See, in the code above the &lt;b&gt;TObject.Create()&lt;/b&gt; has been hidden :-) &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
There is another consideration though: What happens if we &lt;i&gt;overload &lt;/i&gt;the &lt;b&gt;Create &lt;/b&gt;constructor?&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //this one takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aParameter1: string; aParameter2: Integer ); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aThisTakesAChar: Char); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aThisTakesAnInteger: Integer); overload;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
By overloading the &lt;b&gt;Create &lt;/b&gt;constructor we have made the &lt;b&gt;TObject.Create()&lt;/b&gt; visible again. If we want to keep it hidden, then we should avoid overloading. For that, you can simply use a different name for the new constructors being added. Something like this:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;TSomeClass = class(TObject)&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;public&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //this one takes two parameters, and hides the TObject.Create()&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create(aParameter1: string; aParameter2: Integer );&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create2(aThisTakesAChar: Char); &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; constructor Create3(aThisTakesAnInteger: Integer); &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
Now the &lt;b&gt;TObject.Create() &lt;/b&gt;constructor is hidden again.&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;u&gt;Consuming code&lt;/u&gt;:&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;var&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeObject: TSomeClass;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;begin&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; SomeObject:= TSomeClass.Create; //This does not compile!&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create('Hello People!', 12);&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create1('H'); &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; //This compiles. Uncomment and try...&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; // SomeObject:= TSomeClass.Create2(12); &lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&lt;br /&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; try&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TODO&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; finally&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeObject.Free;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;&amp;nbsp; end;&lt;/code&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;code&gt;end;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div class="MsoNormal"&gt;
&lt;br /&gt;
Why would someone want to hide the &lt;b&gt;TObject.Create()&lt;/b&gt; anyway? It depends on the situation. I have found this very useful when implementing a singleton class in Delphi. For details refer to: &lt;a href="http://www.yanniel.info/2010/10/singleton-pattern-delphi.html"&gt;Singleton class in Delphi&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
As a conclusion, you can hide the &lt;b&gt;TObject.Create()&lt;/b&gt; constructor by defining a new &lt;i&gt;public&lt;/i&gt; method with the name &lt;b&gt;Create &lt;/b&gt;in the inheriting class. You cannot hide &lt;b&gt;TObject.Create()&lt;/b&gt; by lowering the visibility to &lt;i&gt;protected&lt;/i&gt;, &lt;i&gt;private&lt;/i&gt;, etc.&lt;/div&gt;&lt;a href="http://www.yanniel.info/p/delphi-programming.html" rel="tag" style="display:none"&gt;CodeProject&lt;/a&gt;
</content><link rel="replies" type="application/atom+xml" href="http://www.yanniel.info/feeds/4390956600548964998/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.yanniel.info/2011/08/hide-tobject-create-constructor-delphi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4390956600548964998?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3701737190756431503/posts/default/4390956600548964998?v=2" /><link rel="alternate" type="text/html" href="http://www.yanniel.info/2011/08/hide-tobject-create-constructor-delphi.html" title="Hide the utter &quot;Create&quot; constructor of TObject in Delphi" /><author><name>Yanniel Alvarez</name><uri>https://plus.google.com/105729371576607928124</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-9K1dJtXhjic/AAAAAAAAAAI/AAAAAAAAANg/28iESUKvec0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry></feed>
