<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Svetlin Nakov - Blog</title>
	<link>http://www.nakov.com/blog</link>
	<description>Thoughts on Software Engineering</description>
	<pubDate>Fri, 22 Jan 2010 13:47:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.2</generator>
	<language>en</language>
			<item>
		<title>Course &#8220;High-Quality Programming Code&#8221; at FMI Reached Its Capacity</title>
		<link>http://www.nakov.com/blog/2010/01/22/course-high-quality-programming-code-at-fmi-reached-its-capacity/</link>
		<comments>http://www.nakov.com/blog/2010/01/22/course-high-quality-programming-code-at-fmi-reached-its-capacity/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 13:42:22 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2010/01/22/course-high-quality-programming-code-at-fmi-reached-its-capacity/</guid>
		<description><![CDATA[I was recently warned by students from the Faculty of Mathematics and Informatics (FMI) at Sofia University that our course &#8220;High-Quality Programming Code&#8221; was offered for only 100 students like most elective courses at FMI. We are looking for a way to extend the maximum allowed attendees but we cannot go aside the official administrative rules at the Faculty.
All [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently warned by students from the Faculty of Mathematics and Informatics (FMI) at Sofia University that our <a href="http://codecourse.telerik.com">course &#8220;High-Quality Programming Code&#8221;</a> was offered for only 100 students like most elective courses at FMI. We are looking for a way to extend the maximum allowed attendees but we cannot go aside the official administrative rules at the Faculty.<br />
<h2>All Students from FMI will be Accepted</h2>
<p>The course organizers agree that all FMI students who want to attend this course are welcome to take part in all training activities (lectures, exercises and course projects) even when not officially joined through the official university information system &#8220;SUSI&#8221;. We hope we will be given large enough hall to fit all attendees. Students who pass successfully all their exams and graduate this course will be allowed to reuse their grades for the next year.</p>
<p>For more information keep checking the &#8220;News&#8221; section at the course&#8217;s official Web site: <a href="http://codecourse.telerik.com">http://codecourse.telerik.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2010/01/22/course-high-quality-programming-code-at-fmi-reached-its-capacity/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Course &#8220;High-Quality Programming Code&#8221; in FMI and TU-Sofia</title>
		<link>http://www.nakov.com/blog/2010/01/19/course-high-quality-programming-code-in-fmi-and-tu-sofia/</link>
		<comments>http://www.nakov.com/blog/2010/01/19/course-high-quality-programming-code-in-fmi-and-tu-sofia/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 11:01:20 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2010/01/19/course-high-quality-programming-code-in-fmi-and-tu-sofia/</guid>
		<description><![CDATA[Starting from February 2010 I will lead a team of software engineering professionals from Telerik Corporation who will teach the course &#8220;High-Quality Programming Code&#8221; in the Faculty of Mathematics and Informatics (FMI) at Sofia University and at the Technical Univesity - Sofia (TU-Sofia). The course complements the fundamental university education with important software development and code construction concepts and best practices. [...]]]></description>
			<content:encoded><![CDATA[<p>Starting from February 2010 I will lead a team of software engineering professionals from <a href="http://www.telerik.com">Telerik Corporation</a> who will teach the <a href="http://codecourse.telerik.com">course &#8220;High-Quality Programming Code&#8221;</a> in the <a href="http://fmi.uni-sofia.bg">Faculty of Mathematics and Informatics (FMI) at Sofia University</a> and at the <a href="http://www.tu-sofia.bg">Technical Univesity - Sofia</a> (TU-Sofia). The course complements the fundamental university education with important software development and code construction concepts and best practices. The outcomes for the students are the acquisition of knowledge and skills for building high-quality programming code, practical skills for code refactoring and unit testing.<br />
<h2>Course Organizers</h2>
<p>The course is organized by <a href="http://www.nakov.com/blog">Svetlin Nakov</a> and his team with the cooperation of the <a href="http://dse.fmi.uni-sofia.bg">Department of Software Technologies in FMI</a> and the <a href="http://studsavet.com/">Students Council in TU-Sofia</a>. The course is supported and sponsored by <a href="http://www.telerik.com">Telerik Corporation</a> (large Bulgarian software development company recently listed in the <a href="http://www.redherring.com/Home/26281">Red Herring: Global 100 Winners</a>).<br />
<h2>Course Annotation</h2>
<p>The „High-quality programming code” course objective is to introduce the students to the principles of high-quality programming code construction during the software development process. The quality of the code is discussed in its most important characteristics – correctness, readability and maintainability. The principles of construction of high-quality class hierarchies, classes and methods are explained. Two fundamental concepts – “loose coupling” and “strong cohesion” are defined and their effect on the construction of classes and subroutines is discussed. Some advices for correctly dealing with the variables and data are given, as well as directions for correct naming of the variables and the rest elements of the program. Best practices for organization of the logical programming constructs are explained. Some methodologies for testing, debugging and code optimization are introduced. Attention is given also to the “refactoring” as a technique for improving the quality of the existing code. The principles of good formatting of the code are defined and explained. The concept of “self-documenting code” as a programming style is introduced. The techniques and practices for constructing high-quality programming code discussed in the course are independent of the programming languages.<br />
<h2>Training Program</h2>
<ol>
<li>Course Overview. Introduction to High-Quality Programming Code. Entrance Project</li>
<li>Fundamentals of Software Engineering</li>
<li>Naming Identifiers in the Source Code. Naming Classes, Methods, Variables, Parameters and Other Elements of the Code</li>
<li>Designing High-Quality Classes and Class Hierarchies. Best Practices in the Object-Oriented Design</li>
<li>High-Quality Methods. Strong Cohesion and Loose Coupling</li>
<li>Using Variables, Data, Expressions and Constants Correctly</li>
<li>Using Control Structures, Conditional Statements and Loops Correctly</li>
<li>Correctly Formatting the Code. Code Documentation, Comments and Self-Documenting Code. Code Conventions</li>
<li>Defensive Programming. Using Exceptions Correctly. Performance Tuning and Code Optimization</li>
<li>Code Integration. Refactoring Existing Code to Improve Its Quality</li>
<li>Software Quality Assurance. Testing and Debugging. Unit Testing. Test-Driven Development</li>
<li>Development Tools. Development Environments. Change Management Systems. Code Analysis Tools. Automated Testing Tools. Automated Build Tools. Continuous Integration Tools</li>
<li>Test Covering the All Studied Topics</li>
<li>Course Projects: Assignment, Guidelines and Discussion</li>
<li>Psychology of Computer Programming</li>
</ol>
<h2>Lecturers Team</h2>
<ul>
<li>Svetlin Nakov – Manager Technical Training, Telerik Corporation, Telerik Academy, Blog: <a href="http://www.nakov.com/blog">http://www.nakov.com/blog</a></li>
<li>Vesko Kolev – Software Engineer, Telerik Corporation, Blog: <a href="http://veskokolev.blogspot.com/">http://veskokolev.blogspot.com</a></li>
<li>Tsvyatko Konov – Software Engineer, Telerik Corporation, Blog: <a href="http://tsvyatkokonov.blogspot.com/">http://tsvyatkokonov.blogspot.com/</a></li>
<li>Yordan Dimitrov – Software Engineer, Telerik Corporation, Blog: <a href="http://blogs.telerik.com/jordandimitrov/">http://blogs.telerik.com/jordandimitrov/</a></li>
<li>Radoslav Kirilov – Software Engineer, Telerik Corporation, Blog: <a href="http://radoslavkirilov.blogspot.com/">http://radoslavkirilov.blogspot.com/</a></li>
<li>Stefan Dobrev – Software Engineer, Telerik Corporation, Blog: <a href="http://blogs.telerik.com/stefandobrev/">http://blogs.telerik.com/stefandobrev/</a></li>
<li>Nikolay Ganchev – Software Engineer, Telerik Corporation</li>
<li>Ivaylo Bratoev – Software Engineer, Telerik Corporation</li>
</ul>
<h2>Requirements to the Students</h2>
<ul>
<li>Computer programming skills</li>
<li>Knowledge of object-oriented programming</li>
<li>English language</li>
</ul>
<h2>Assesment and Exams</h2>
<p>Assessment is based on test (theory) and course project (practice). The test consists of 40 questions covering the course content. The course project has two parts: entrance project (small programming problem that should be solved in C#, Java or C++) and final project (refactoring of low-quality code and adding unit tests).<br />
<h2>Official Web Site</h2>
<p>Visit the official Web site of the course &#8220;High-Quality Programming Code&#8221;: <a href="http://codecourse.telerik.com/">http://codecourse.telerik.com/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2010/01/19/course-high-quality-programming-code-in-fmi-and-tu-sofia/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Course &#8220;Web Applications Development with .NET Framework and ASP.NET&#8221; in TU-Sofia</title>
		<link>http://www.nakov.com/blog/2010/01/18/course-web-applications-development-with-net-framework-and-aspnet-in-tu-sofia/</link>
		<comments>http://www.nakov.com/blog/2010/01/18/course-web-applications-development-with-net-framework-and-aspnet-in-tu-sofia/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 12:24:40 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2010/01/19/course-web-applications-development-with-net-framework-and-aspnet-in-tu-sofia/</guid>
		<description><![CDATA[Starting from February 2010 I will lead a team of .NET software engineering professionals who will teach the course &#8220;Web Applications Development with .NET Framework and ASP.NET&#8221; at the Technical Univesity - Sofia (TU-Sofia). The course complements the fundamental university education with contemporary Web development technologies. The outcomes for the students are the acquisition of practical skills for building rich-data [...]]]></description>
			<content:encoded><![CDATA[<p>Starting from February 2010 I will lead a team of .NET software engineering professionals who will teach the <a href="http://aspnetcourse.telerik.com">course &#8220;Web Applications Development with .NET Framework and ASP.NET&#8221;</a> at the <a href="http://www.tu-sofia.bg">Technical Univesity - Sofia</a> (TU-Sofia). The course complements the fundamental university education with contemporary Web development technologies. The outcomes for the students are the acquisition of practical skills for building rich-data Web applications based on .NET Framework, LINQ-to-SQL, SQL Server, ASP.NET, AJAX and Silverlight.</p>
<h2>Course Organizers</h2>
<p>The course is organized by the <a href="http://studsavet.com/">Students Council in TU-Sofia</a> who invited <a href="http://www.nakov.com/blog">Svetlin Nakov</a> and his team to teach it for all students in TU-Sofia. The course is supported and sponsored by <a href="http://www.telerik.com">Telerik Corporation</a> (large Bulgarian software development company which was recently listed in the <a href="http://www.redherring.com/Home/26281">Red Herring: Global 100 Winners</a>).</p>
<h2>Course Annotation</h2>
<p>The „Web Applications Development with .NET Framework and ASP.NET” course objective is to introduce the students to the fundamentals of C#, .NET Framework, databases and Web application development with ASP.NET and AJAX. Students will learn how to build dynamic data-driven Web applications with SQL Server and ASP.NET. The course starts with the basics of C# language (data types, expressions, statements, loops, arrays, methods, strings, collections, exceptions, etc.), object-oriented programming with C# (classes and interfaces, constructors, properties, events, methods, etc.), relational databases, SQL language and SQL Server, data access technologies (LINQ and LINQ-to-SQL). The main focus is on Web technologies, starting from HTTP, HTML, CSS and JavaScript, through the fundamentals of ASP.NET and ASP.NET Web Forms. Advanced topics include building rich-data applications with ASP.NET data-bound controls, using master pages, AJAX and Silverlight. All topics covered in the course will be demonstrated in a practical session demonstrating how to build building a sample dynamic rich-data Web application from scratch, step-by-step.</p>
<h2>Training Program</h2>
<ol>
<li><strong>Course Overview</strong> – Presenting the Course Objectives, Lecturers, Exams, etc.<strong>.NET Framework Overview</strong> – .NET, .NET Framework, CLR, MSIL, Assemblies, CTS, .NET languages</li>
<li><strong>C# Language Overview – Part I</strong> – Data Types, Operators, Expressions, Statements, Console I/O, Conditional Statements, Loops, Arrays, Methods</li>
<li><strong>C# Language Overview – Part II</strong> – Creating and Using Objects, Exceptions, Strings, Generics, Collections, Attributes</li>
<li><strong>Object-Oriented Programming with C#</strong> – Defining Classes, Constructors, Properties, Methods, Delegates, Events, Static Members, Interfaces, Inheritance, Polymorphism</li>
<li><strong>Databases, SQL and MS SQL Server</strong> – RDBMS, SQL Language, SQL SELECT, Joins, Aggregate Functions, Grouping, SQL INSERT, SQL UPDATE, SQL DELETE, MS SQL Server, SQL Server Management Studio</li>
<li><strong>LINQ and LINQ-to-SQ</strong>L – LINQ Operators and Expressions, Projections, Conversions, Aggregations, LINQ-to-SQL, Visual Studio LINQ-to-SQL Designer, Using DataContext to Read / Create / Update / Delete Data</li>
<li><strong>Web Technologies Basics</strong> – HTTP, HTML, Text, Images, Tables, Forms, CSS, JavaScript</li>
<li><strong>ASP.NET – Part I</strong> – ASP.NET Web Forms, Code Behind Pages, Page Execution Model, Web Server Controls, HTML Server Controls, Creating Simple Web Applications</li>
<li><strong>ASP.NET – Part II</strong> – Data Binding and Data-Bound Controls: Data Sources (LinqDataSource, ObjectDataSoucre), GridView, FormView, DetailsView, DataList, Repeater, ListView, Pager</li>
<li><strong>ASP.NET – Part III</strong> – Session and State Management, Master Pages and Navigation, User Controls, Web.config, ASP.NET Membership, IIS and Deployment</li>
<li><strong>ASP.NET AJAX</strong> – ScriptManager, UpdatePanel, AJAX Control Toolkit</li>
<li><strong>Silverlight</strong> – XAML, Text, Images, Graphics, Shapes, Creating Silverlight Applications, Text Controls, Buttons, List Controls, Data Binding and Data-Bound Controls</li>
<li><strong>Practical Project Demo</strong> – Creating Dynamic Rich-Data ASP.NET Web Application – Step-by-Step Live Demo</li>
<li><strong>Additional Topic #1</strong> – Student will Suggest Interesting Topics</li>
<li><strong>Additional Topic #2</strong> – Student will Suggest Interesting Topics</li>
</ol>
<h2>Lecturers Team</h2>
<ul>
<li>Svetlin Nakov – Manager Technical Training, Telerik Corporation, Telerik Academy, Blog: <a href="http://www.nakov.com/blog">http://www.nakov.com/blog</a></li>
<li>Ivaylo Hristov – Managing Partner, Komfo Bulgaria, Blog: <a href="http://ivaylo-hristov.net/">http://ivaylo-hristov.net/</a></li>
<li>Mihail Stoynov – Technical lead, Materna Bulgaria, Blog: <a href="http://mihail.stoynov.com/blog/">http://mihail.stoynov.com/blog/</a></li>
<li>Ventsislav Popov – Developer, Crossroad</li>
<li>Branislav Abadjimarinov – Senior .NET Developer, ProPeople, Blog: <a href="http://abadjimarinov.net/">http://abadjimarinov.net/</a></li>
<li>Svetlin Ralchev – software engineer, Telerik Corporation, Blog: <a href="http://blog.ralch.com/">http://blog.ralch.com/</a></li>
<li>Ivaylo Bratoev – software engineer, Telerik Corporation, Blog: <a href="http://blogs.telerik.com/ivaylobratoev/">http://blogs.telerik.com/ivaylobratoev/</a></li>
</ul>
<h2>Requirements to Attend the Course</h2>
<ul>
<li>Basic computer programming skills</li>
<li>Basic understanding of object-oriented-programming (OOP) concepts</li>
<li>English language</li>
</ul>
<h2>Assesment and Exams</h2>
<p>Students will be assigned to develop as a practical project dynamic Web application based on .NET Framework, ASP.NET Web Forms, SQL Server and LINQ-to-SQL. Sample projects: dynamic photo album, CMS system, blog system, dating site, online game, Web mail, etc.Authors of the best projects will be awarded by our sponsor Telerik.</p>
<h2>Official Web Site</h2>
<p>Visit the official Web site of the course &#8220;Web Applications Development with .NET Framework and ASP.NET&#8221;: <a href="http://aspnetcourse.telerik.com/">http://aspnetcourse.telerik.com/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2010/01/18/course-web-applications-development-with-net-framework-and-aspnet-in-tu-sofia/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Seminar &#8220;Practical Software Engineering&#8221; in TU-Sofia - 8 February 2010</title>
		<link>http://www.nakov.com/blog/2010/01/01/seminar-practical-software-engineering-in-tu-sofia-8-february-2010/</link>
		<comments>http://www.nakov.com/blog/2010/01/01/seminar-practical-software-engineering-in-tu-sofia-8-february-2010/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 13:01:47 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2010/01/19/seminar-practical-software-engineering-in-tu-sofia-8-february-2010/</guid>
		<description><![CDATA[I was recently invited by the Board of European Students of Technology (B.E.S.T. Sofia) to give a talk on &#8220;Practical Software Engineering Fundamentals&#8221; in the Technical University of Sofia. The event is designed for students who wants to become software engineers.

Venue: TU-Sofia, hall 1153
Date: 8 February (Monday), 18:00

Software engineering defines the software development project lifecycle as sequence of activities, [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently invited by the <a href="http://www.bestsofia.org/">Board of European Students of Technology (B.E.S.T. Sofia)</a> to give a talk on &#8220;Practical Software Engineering Fundamentals&#8221; in the Technical University of Sofia. The event is designed for students who wants to become software engineers.</p>
<ul>
<li>Venue: TU-Sofia, hall 1153</li>
<li>Date: 8 February (Monday), 18:00</li>
</ul>
<p>Software engineering defines the software development project lifecycle as sequence of activities, such as requirements analysis, architecture, design, code construction, testing, debugging, integration, deployment, maintenance, etc., which are performed following the practices of given development methodology applying a set of project management activities for planning, monitoring and controlling the project.</p>
<p>In this talk the speaker Svetlin Nakov will introduce the audience with the most important software engineering activities and will explain the typical software project lifecycle. Comprehensive examples will be given along with the theoretical fundamentals. Typical documents and templates used during the software development process will be presented including: software requirements specifications (SRS), software design documents (SDD), test plans, project plans, etc.</p>
<p>The event is supported by <a href="http://academy.telerik.com">Telerik Academy</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2010/01/01/seminar-practical-software-engineering-in-tu-sofia-8-february-2010/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Telerik Academy Officially Launched Free Software Development Courses for 100 Students from February 2010</title>
		<link>http://www.nakov.com/blog/2009/12/15/telerik-academy-officially-launched-free-software-development-courses-for-100-students-from-february/</link>
		<comments>http://www.nakov.com/blog/2009/12/15/telerik-academy-officially-launched-free-software-development-courses-for-100-students-from-february/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 19:13:18 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/12/15/telerik-academy-officially-launched-free-software-development-courses-for-100-students-from-february/</guid>
		<description><![CDATA[In the last few months I am working as full-time consultant for the training initiatives in Telerik. It is really an exciting company and I really enjoy my job as manager of the technical training and university relations. I still can&#8217;t believe that Telerik is really perfectly organized company, beyond my expectations and even dreams. It is unusual company [...]]]></description>
			<content:encoded><![CDATA[<p>In the last few months I am working as full-time consultant for the training initiatives in <a target="_blank" href="http://www.telerik.com">Telerik</a>. It is really an exciting company and I really enjoy my job as manager of the technical training and university relations. I still can&#8217;t believe that Telerik is really perfectly organized company, beyond my expectations and even dreams. It is unusual company with specific culture, structure and traditions. Unlike traditional companies our CEO sits behind me along with few developers, not in a separate &#8220;big boss room&#8221;. I will blog about Telerik in details another day. Now let me present my main work at Telerik.</p>
<h2>Telerik Academy</h2>
<p><a href="http://academy.telerik.com"><br />
<img hspace="10" border="1" src="/blog/wp-content/uploads/2010/01/telerik-academy-banner.jpg" alt="Telerik Academy" align="left" title="Telerik Academy" /></a>Today I launched a new long-term training project called &#8220;<a target="_blank" href="http://academy.telerik.com">Telerik Academy</a>&#8220;. Telerik Academy is an initiative of <a target="_blank" href="http://www.telerik.com">Telerik Corporation</a> aiming to provide free real-world practical training for young people who want to turn into skillful .NET software engineers and join the company development teams. The training complements the traditional University education with the cutting edge industry technologies from Microsoft and best practices in software engineering.</p>
<p>During the Telerik Academy training program highly motivated young people are attracted and candidates covering the program requirements are trained free of charge in the fundamentals of computer programming, logical algorithmic thinking, data structures, algorithms, problem solving and object-oriented concepts. The best of them are selected through exams and interviews and continue to the next level of training – .NET Development Essentials course, covering the .NET Framework class library, databases, SQL Server and LINQ, Web technologies, ASP.NET and AJAX, Windows Forms, WPF and Silverlight, as well as software engineering. Having successfully finished this stage the top students qualify for an additional specialized course in one of the following technological directions used in Telerik: ASP.NET &amp; AJAX, Windows Presentation Foundation (WPF) and Silverlight, Windows Forms and Data-Centric Development. Finally, those who graduate will be presented with the opportunity to join the Telerik team and help us deliver exceptional software to the world.</p>
<h2>Telerik Pays to Students to Study .NET Technologies</h2>
<p>Telerik pays its trainees at Telerik Academy to learn the .NET technologies for few months and provides job for the best graduates. We are growing even during the global financial crisis and Telerik Academy is our way to grow with highly-motivated and skillful junior developers. Our learning track takes 6 months:</p>
<ul>
<li>Foundations of C# Programming (Part 1) - 100 people, free of charge, 1 month, 8 hours/week, staring in February</li>
<li>Foundations of C# Programming (Part 2) - 50 people (filtered by exam), free of charge, 1 month, 12 hours/week, staring in Marh</li>
<li>.NET Programming Essentials - 15-20 students, 3 months, 4 hours/day, staring in April</li>
<li>ASP.NET / Windows Forms / Silverlight &amp; WPF / Data-Centric - 10-15 students, paid to be trained, 1 month, 8 hours/day</li>
<li>All successfully graduated people start work in Telerik</li>
</ul>
<h2>Program Requirements</h2>
<p>The minimum requirements for any candidate are:</p>
<ul class="checkBullet">
<li>Ability and willingness to work at full time (8 hours/daily) - after the first 2 months</li>
<li>High motivation to become software engineering professional</li>
<li>Technical English</li>
<li>Computer literacy</li>
<li>Long term commitment</li>
</ul>
<h2>Apply for Telerik Academy</h2>
<p>To apply for free 6-months .NET training visit the <a target="_blank" href="http://academy.telerik.com">Telerik Academy official web site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/12/15/telerik-academy-officially-launched-free-software-development-courses-for-100-students-from-february/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Svetlin Nakov is No Longer Involved in the National Academy for Software Development (NASD)</title>
		<link>http://www.nakov.com/blog/2009/12/01/svetlin-nakov-is-no-longer-involved-in-national-academy-for-software-development-nasd/</link>
		<comments>http://www.nakov.com/blog/2009/12/01/svetlin-nakov-is-no-longer-involved-in-national-academy-for-software-development-nasd/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 19:37:46 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/12/01/svetlin-nakov-is-no-longer-involved-in-national-academy-for-software-development-nasd/</guid>
		<description><![CDATA[Starting from March 2009 I left the National Academy for Software Development (NASD). NASD was really nice project and it was running successfully for few years but the idea changed so much that from some point in 2008 I was no longer able to enjoy doing this work.
Why I left NASD?
1) My dream was about running a [...]]]></description>
			<content:encoded><![CDATA[<p>Starting from March 2009 I left the <a target="_blank" href="http://academy.devbg.org">National Academy for Software Development (NASD)</a>. NASD was really nice project and it was running successfully for few years but the idea changed so much that from some point in 2008 I was no longer able to enjoy doing this work.</p>
<h2>Why I left NASD?</h2>
<p>1) My dream was about running a software development training center where people get 100% free training and this was really achieved in 2006, 2007 and 2008. At some point the trainings became paid and I was no longer motivated to participate.</p>
<p>2) I really enjoy teaching young and motivated people in software technologies and software engineering and I really do this job well but NASD was fast growing (30 employees in 2008) and at some moment the things got out of my control. Initially I teached all the courses and the teaching quality was superior. Later we employed junior trainers who was good but not the same level like me. Some business partners of mine told me that they want me to teach the people personally. This was not possible because in 2007 and 2008 I was team leader of 5 to 7 software development projects in the same time and coordinator of all training courses. At some moments we had 8 courses running in parallel. We employed few developers who was working on projects in the day and on trainings in the evenings. Most of them were really good developers and good trainers, but people still asked me to teach the people myself. This was the second reason to leave NASD and to find a different way to conduct software development trainings.</p>
<h2>What will Happen with NASD?</h2>
<p>Please don&#8217;t ask me this question. I really don&#8217;t know and this is out of my control! NASD was founded by me (with few partners) but I was never been CEO of NASD Ltd. and I even had a minor share of it all the time. I left NASD when the trainings became paid and some students needed to pay for some courses that were initially offered as free. I didn&#8217;t like this to happen and I left this company. Now my former partners are driving it. I am no longer involved in any activity that NASD is performing.</p>
<h2>Free Trainings, New Academy or What is Next?</h2>
<p>This is a good question. In November 2009 I joined <a target="_blank" href="http://www.telerik.com">Telerik Corporation</a> to organize software development trainings for producing skillful .NET software engineers. Now I lead the project called <a target="_blank" href="http://academy.telerik.com">Telerik Academy</a> that is bringing me back to my initial idea of creating a software development academy. We provide free software development courses and I personally teach all the students in Telerik Academy. I feel closer to my dreams about teaching motivated young people in software engineering and technologies free of charge and preparing them for the real world industrial software development. Note that Telerik Academy is not a successor of NASD. I just moved to a new job. I believe the results will be outstanding like in the first days of NASD.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/12/01/svetlin-nakov-is-no-longer-involved-in-national-academy-for-software-development-nasd/feed/</wfw:commentRss>
		</item>
		<item>
		<title>X.509 Certificate Validation in Java: Build and Verify Chain and Verify CLR with Bouncy Castle</title>
		<link>http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/</link>
		<comments>http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:10:03 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[java]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/</guid>
		<description><![CDATA[For one of my recent projects I needed to implement X.509 certificate validation library that validates a certificate across given set of trusted root certificated and a set of intermediate certificate. Initially I thought this is a problem that has already out-of-the-box solution in BouncyCastle but the CRL verification was found to be unpleasant to [...]]]></description>
			<content:encoded><![CDATA[<p>For one of my recent projects I needed to implement X.509 certificate validation library that validates a certificate across given set of trusted root certificated and a set of intermediate certificate. Initially I thought this is a problem that has already out-of-the-box solution in BouncyCastle but the CRL verification was found to be unpleasant to implement and not available out-of-the-box.<br />
The task was formulated as follows: given a X.509 certificate and a set of trusted root certificates and a set of intermediate certificates to build a certification chain (if possible) and to extract the CRL distribution point from the certificate (if available) and to check whether the certificate is not revoked. It was required to support HTTP, HTPS, FTP and LDAP based distribution points.<br />
I will not get into more details because I don&#8217;t heve too much time but I think the code is clear enough, so most developers will be able to read, understand and use it:</p>
<textarea name="code" class="java:nocontrols:nogutter" cols="100" rows="20">
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Set;

/**
 * Class for building a certification chain for given certificate and verifying
 * it. Relies on a set of root CA certificates and intermediate certificates
 * that will be used for building the certification chain. The verification
 * process assumes that all self-signed certificates in the set are trusted
 * root CA certificates and all other certificates in the set are intermediate
 * certificates.
 * 
 * @author Svetlin Nakov
 */
public class CertificateVerifier {
	
	/**
	 * Attempts to build a certification chain for given certificate and to verify
	 * it. Relies on a set of root CA certificates and intermediate certificates
	 * that will be used for building the certification chain. The verification
	 * process assumes that all self-signed certificates in the set are trusted
	 * root CA certificates and all other certificates in the set are intermediate
	 * certificates. 
	 * 
	 * @param cert - certificate for validation
	 * @param additionalCerts - set of trusted root CA certificates that will be
	 * 		used as "trust anchors" and intermediate CA certificates that will be
	 * 		used as part of the certification chain. All self-signed certificates
	 * 		are considered to be trusted root CA certificates. All the rest are
	 * 		considered to be intermediate CA certificates.
	 * @return the certification chain (if verification is successful)
	 * @throws CertificateVerificationException - if the certification is not
	 * 		successful (e.g. certification path cannot be built or some
	 * 		certificate in the chain is expired or CRL checks are failed)
	 */
	public static PKIXCertPathBuilderResult verifyCertificate(X509Certificate cert, 
			Set<x509certificate> additionalCerts)
			throws CertificateVerificationException {
		try {
			// Check for self-signed certificate
			if (isSelfSigned(cert)) {
				throw new CertificateVerificationException(
					"The certificate is self-signed.");
			}
			
			// Prepare a set of trusted root CA certificates
			// and a set of intermediate certificates
			Set</x509certificate><x509certificate> trustedRootCerts = new HashSet</x509certificate><x509certificate>();
			Set</x509certificate><x509certificate> intermediateCerts = new HashSet</x509certificate><x509certificate>();
			for (X509Certificate additionalCert : additionalCerts) {
				if (isSelfSigned(additionalCert)) {
					trustedRootCerts.add(additionalCert);
				} else {
					intermediateCerts.add(additionalCert);
				}
			}
			
			// Attempt to build the certification chain and verify it
			PKIXCertPathBuilderResult verifiedCertChain = 
				verifyCertificate(cert, trustedRootCerts, intermediateCerts);
			
			// Check whether the certificate is revoked by the CRL
			// given in its CRL distribution point extension
			CRLVerifier.verifyCertificateCRLs(cert);
	
			// The chain is built and verified. Return it as a result
			return verifiedCertChain;
		} catch (CertPathBuilderException certPathEx) {
			throw new CertificateVerificationException(
				"Error building certification path: " + 
				cert.getSubjectX500Principal(), certPathEx);
		} catch (CertificateVerificationException cvex) {
			throw cvex;
		} catch (Exception ex) {
			throw new CertificateVerificationException(
				"Error verifying the certificate: " + 
				cert.getSubjectX500Principal(), ex);
		}		
	}
	
	/**
	 * Checks whether given X.509 certificate is self-signed.
	 */
	public static boolean isSelfSigned(X509Certificate cert)
			throws CertificateException, NoSuchAlgorithmException,
			NoSuchProviderException {
		try {
			// Try to verify certificate signature with its own public key
			PublicKey key = cert.getPublicKey();
			cert.verify(key);
			return true;
		} catch (SignatureException sigEx) {
			// Invalid signature --> not self-signed
			return false;
		} catch (InvalidKeyException keyEx) {
			// Invalid key --> not self-signed
			return false;
		}
	}
	
	/**
	 * Attempts to build a certification chain for given certificate and to verify
	 * it. Relies on a set of root CA certificates (trust anchors) and a set of
	 * intermediate certificates (to be used as part of the chain).
	 * @param cert - certificate for validation
	 * @param trustedRootCerts - set of trusted root CA certificates
	 * @param intermediateCerts - set of intermediate certificates
	 * @return the certification chain (if verification is successful)
	 * @throws GeneralSecurityException - if the verification is not successful
	 * 		(e.g. certification path cannot be built or some certificate in the
	 * 		chain is expired)
	 */
	private static PKIXCertPathBuilderResult verifyCertificate(X509Certificate cert, Set</x509certificate><x509certificate> trustedRootCerts,
			Set</x509certificate><x509certificate> intermediateCerts) throws GeneralSecurityException {
		
		// Create the selector that specifies the starting certificate
		X509CertSelector selector = new X509CertSelector(); 
	    selector.setCertificate(cert);
	    
	    // Create the trust anchors (set of root CA certificates)
	    Set<trustanchor> trustAnchors = new HashSet</trustanchor><trustanchor>();
	    for (X509Certificate trustedRootCert : trustedRootCerts) {
	    	trustAnchors.add(new TrustAnchor(trustedRootCert, null));
	    }
	    
	    // Configure the PKIX certificate builder algorithm parameters
	    PKIXBuilderParameters pkixParams = 
			new PKIXBuilderParameters(trustAnchors, selector);
		
		// Disable CRL checks (this is done manually as additional step)
		pkixParams.setRevocationEnabled(false);
	
		// Specify a list of intermediate certificates
		CertStore intermediateCertStore = CertStore.getInstance("Collection",
			new CollectionCertStoreParameters(intermediateCerts), "BC");
		pkixParams.addCertStore(intermediateCertStore);
	
		// Build and verify the certification chain
		CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
		PKIXCertPathBuilderResult result = 
			(PKIXCertPathBuilderResult) builder.build(pkixParams);
		return result;
	}
	
}

------------------------

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.X509Extensions;

/**
 * Class that verifies CRLs for given X509 certificate. Extracts the CRL
 * distribution points from the certificate (if available) and checks the
 * certificate revocation status against the CRLs coming from the
 * distribution points. Supports HTTP, HTTPS, FTP and LDAP based URLs.
 * 
 * @author Svetlin Nakov
 */
public class CRLVerifier {

	/**
	 * Extracts the CRL distribution points from the certificate (if available)
	 * and checks the certificate revocation status against the CRLs coming from
	 * the distribution points. Supports HTTP, HTTPS, FTP and LDAP based URLs.
	 * 
	 * @param cert the certificate to be checked for revocation
	 * @throws CertificateVerificationException if the certificate is revoked
	 */
	public static void verifyCertificateCRLs(X509Certificate cert)
			throws CertificateVerificationException {
		try {
			List<string> crlDistPoints = getCrlDistributionPoints(cert);
			for (String crlDP : crlDistPoints) {
				X509CRL crl = downloadCRL(crlDP);
				if (crl.isRevoked(cert)) {
					throw new CertificateVerificationException(
							"The certificate is revoked by CRL: " + crlDP);
				}
			}
		} catch (Exception ex) {
			if (ex instanceof CertificateVerificationException) {
				throw (CertificateVerificationException) ex;
			} else {
				throw new CertificateVerificationException(
						"Can not verify CRL for certificate: " + 
						cert.getSubjectX500Principal());
			}
		}
	}

	/**
	 * Downloads CRL from given URL. Supports http, https, ftp and ldap based URLs.
	 */
	private static X509CRL downloadCRL(String crlURL) throws IOException,
			CertificateException, CRLException,
			CertificateVerificationException, NamingException {
		if (crlURL.startsWith("http://") || crlURL.startsWith("https://")
				|| crlURL.startsWith("ftp://")) {
			X509CRL crl = downloadCRLFromWeb(crlURL);
			return crl;
		} else if (crlURL.startsWith("ldap://")) {
			X509CRL crl = downloadCRLFromLDAP(crlURL);
			return crl;
		} else {
			throw new CertificateVerificationException(
					"Can not download CRL from certificate " +
					"distribution point: " + crlURL);
		}
	}

	/**
	 * Downloads a CRL from given LDAP url, e.g.
	 * ldap://ldap.infonotary.com/dc=identity-ca,dc=infonotary,dc=com
	 */
	private static X509CRL downloadCRLFromLDAP(String ldapURL) 
			throws CertificateException, NamingException, CRLException, 
			CertificateVerificationException {
		Hashtable</string><string , String> env = new Hashtable</string><string , String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY, 
				"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, ldapURL);

        DirContext ctx = new InitialDirContext(env);
        Attributes avals = ctx.getAttributes("");
        Attribute aval = avals.get("certificateRevocationList;binary");
        byte[] val = (byte[])aval.get();
        if ((val == null) || (val.length == 0)) {
        	throw new CertificateVerificationException(
        			"Can not download CRL from: " + ldapURL);
        } else {
        	InputStream inStream = new ByteArrayInputStream(val);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
        	X509CRL crl = (X509CRL)cf.generateCRL(inStream);
        	return crl;
        }
	}
	
	/**
	 * Downloads a CRL from given HTTP/HTTPS/FTP URL, e.g.
	 * http://crl.infonotary.com/crl/identity-ca.crl
	 */
	private static X509CRL downloadCRLFromWeb(String crlURL)
			throws MalformedURLException, IOException, CertificateException,
			CRLException {
		URL url = new URL(crlURL);
		InputStream crlStream = url.openStream();
		try {
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509CRL crl = (X509CRL) cf.generateCRL(crlStream);
			return crl;
		} finally {
			crlStream.close();
		}
	}

	/**
	 * Extracts all CRL distribution point URLs from the "CRL Distribution Point"
	 * extension in a X.509 certificate. If CRL distribution point extension is
	 * unavailable, returns an empty list. 
	 */
	public static List</string><string> getCrlDistributionPoints(
			X509Certificate cert) throws CertificateParsingException, IOException {
		byte[] crldpExt = cert.getExtensionValue(
				X509Extensions.CRLDistributionPoints.getId());
		if (crldpExt == null) {
			List</string><string> emptyList = new ArrayList</string><string>();
			return emptyList;
		}
		ASN1InputStream oAsnInStream = new ASN1InputStream(
				new ByteArrayInputStream(crldpExt));
		DERObject derObjCrlDP = oAsnInStream.readObject();
		DEROctetString dosCrlDP = (DEROctetString) derObjCrlDP;
		byte[] crldpExtOctets = dosCrlDP.getOctets();
		ASN1InputStream oAsnInStream2 = new ASN1InputStream(
				new ByteArrayInputStream(crldpExtOctets));
		DERObject derObj2 = oAsnInStream2.readObject();
		CRLDistPoint distPoint = CRLDistPoint.getInstance(derObj2);
		List</string><string> crlUrls = new ArrayList</string><string>();
		for (DistributionPoint dp : distPoint.getDistributionPoints()) {
            DistributionPointName dpn = dp.getDistributionPoint();
            // Look for URIs in fullName
            if (dpn != null) {
                if (dpn.getType() == DistributionPointName.FULL_NAME) {
                    GeneralName[] genNames = GeneralNames.getInstance(
                        dpn.getName()).getNames();
                    // Look for an URI
                    for (int j = 0; j < genNames.length; j++) {
                        if (genNames[j].getTagNo() == GeneralName.uniformResourceIdentifier) {
                            String url = DERIA5String.getInstance(
                                genNames[j].getName()).getString();
                            crlUrls.add(url);
                        }
                    }
                }
            }
		}
		return crlUrls;
	}

}

------------------------

import java.security.cert.PKIXCertPathBuilderResult;

/**
 * This class keeps the result from the certificate verification
 * process. If the the certificate is verified as valid, the built
 * certification chain is stored in the Result property. If the
 * certificate is invalid, the problem is stored in the Exception
 * property. 
 * 
 * @author Svetlin Nakov
 */
public class CertificateVerificationResult {
	private boolean valid;
	private PKIXCertPathBuilderResult result;
	private Throwable exception;
	
	/**
	 * Constructs a certificate verification result for valid
	 * certificate by given certification path.
	 */
	public CertificateVerificationResult(
			PKIXCertPathBuilderResult result) {
		this.valid = true;
		this.result = result;
	}

	/**
	 * Constructs a certificate verification result for invalid
	 * certificate by given exception that keeps the problem
	 * occurred during the verification process.
	 */
	public CertificateVerificationResult(Throwable exception) {
		this.valid = false;
		this.exception = exception;
	}

	public boolean isValid() {
		return valid;
	}

	public PKIXCertPathBuilderResult getResult() {
		return result;
	}

	public Throwable getException() {
		return exception;
	}	
}

------------------------

/**
 * This class wraps an exception that could be thrown during
 * the certificate verification process.
 * 
 * @author Svetlin Nakov
 */
public class CertificateVerificationException extends Exception {
	private static final long serialVersionUID = 1L;

	public CertificateVerificationException(String message, Throwable cause) {
        super(message, cause);
    }

	public CertificateVerificationException(String message) {
        super(message);
    }
}

</textarea>
<p>I hope the above coude could be useful to anybody trying to build and validate X.509 certificate chain and check the CRL revocation status.<br />
</string></trustanchor></x509certificate></p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/12/01/x509-certificate-validation-in-java-build-and-verify-chain-and-verify-clr-with-bouncy-castle/feed/</wfw:commentRss>
		</item>
		<item>
		<title>NHibernate Lazy Loading BLOB column</title>
		<link>http://www.nakov.com/blog/2009/11/30/nhibernate-lazy-loading-blob-column/</link>
		<comments>http://www.nakov.com/blog/2009/11/30/nhibernate-lazy-loading-blob-column/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 20:24:07 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/11/30/nhibernate-lazy-loading-blob-column/</guid>
		<description><![CDATA[For my last project we used Oracle 10g and NHibernate ORM framework (the project was started 4-5 yars ago, long before LINQ and ADO.NET Entity Framework). I had a database table which holds payment information along with scanned images of the payment documents. Usually such tables are mapped with a class fully corresponding to the table fields. The usual approach [...]]]></description>
			<content:encoded><![CDATA[<p>For my last project we used Oracle 10g and NHibernate ORM framework (the project was started 4-5 yars ago, long before LINQ and ADO.NET Entity Framework). I had a database table which holds payment information along with scanned images of the payment documents. Usually such tables are mapped with a class fully corresponding to the table fields. The usual approach works well but has a performance problem: when the table needs to be displayed, the binary images holding the payment documents do not need to be loaded from the database because they consume much memory and take time to load. NHibernate supports lazy loading for associations only but does not support lazy column / property loading. To achieve a normal performance I needed to do a quick hack and I believe it could be useful for other projects so I want to shera it with the community.</p>
<p>The hack is to map all columns of the database table except the large binary column (BLOB type in Oracle). The large binary column is handle differently with additional select / update operations. See the payment entity definition below:</p>
<textarea name="code" class="csharp:nocontrols:nogutter" cols="100" rows="20">
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Mapping.Attributes;

namespace Example
{
    [Class(0, Table = "PAYMENTS")]
    [XmlType("payment")]
    public class Payment
    {
        private int id;
        private DateTime paymentDate;
        private decimal paymentAmmount;
        private string paymentRefNumber;
        private string paymentDocumentFileName;

        private static Dao<payment> dao = new Dao</payment><payment>();

        [Id(1, Column = "ID", Type = "System.Int32"),
            Generator(2, Class = "native"), Param(3, Content = "SQ_PAYMENTS", Name = "sequence")]
        [XmlElement("id")]
        public virtual int ID
        {
            get { return id; }
            set { id = value; }
        }

        [Property(Column = "PAYMENT_DATE", Type = "System.DateTime")]
        [XmlElement("paymentDate")]
        public virtual DateTime PaymentDate
        {
            get { return paymentDate; }
            set { paymentDate = value; }
        }

        [Property(Column = "PAYMENT_AMMOUNT", Type = "System.Decimal")]
        [XmlElement("ammount")]
        public virtual decimal PaymentAmmount
        {
            get { return paymentAmmount; }
            set { paymentAmmount = value; }
        }

        [Property(Column = "PAYMENT_REF_NUMBER", Type = "System.String")]
        [XmlElement("paymentRefNumber")]
        public virtual string PaymentRefNumber
        {
            get { return paymentRefNumber; }
            set { paymentRefNumber = value; }
        }

        [Property(Column = "PAYMENT_DOC_FILE_NAME", Type = "System.String")]
        [XmlElement("paymentDocumentFileName")]
        public virtual string PaymentDocumentFileName
        {
            get { return paymentDocumentFileName; }
            set { paymentDocumentFileName = value; }
        }

        public static IList</payment><payment> GetAll()
        {
            return dao.GetAll("paymentDate");
        }

        public byte[] PaymentDocument
        {
            // Implement lazy loading for the PAYMENT_DOC blob (for better performance)
            get
            {
                ISession hbSession = NHibernateSessionManager.Instance.GetSession();
                ISQLQuery query = hbSession.CreateSQLQuery("SELECT PAYMENT_DOC FROM PAYMENTS WHERE ID=:payment_id");
                query.SetParameter("payment_id", this.ID);
                byte[] paymentDoc = (byte[])query.UniqueResult();
                return paymentDoc;
            }
            set
            {
                if (this.ID == 0)
                {
                    throw new Exception("Can not assing PaymentDocument for non-persistent payments!");
                }
                ISession hbSession = NHibernateSessionManager.Instance.GetSession();
                ISQLQuery query = hbSession.CreateSQLQuery(
                    "UPDATE PAYMENTS SET PAYMENT_DOC=:payment_doc WHERE ID=:payment_id");
                query.SetParameter("payment_id", this.ID);
                query.SetParameter("payment_doc", value);
                query.ExecuteUpdate();
            }
        }

        public static Payment Save(Payment payment)
        {
            return dao.Save(payment);
        }
    }
}
</textarea>
<p>The database schema of the PAYMENTS table is as follows:</p>
<textarea name="code" class="sql:nocontrols:nogutter" cols="100" rows="20">
CREATE TABLE PAYMENTS(
  ID NUMBER(6,0) NOT NULL,
  PAYMENT_DATE DATE NOT NULL,
  PAYMENT_AMMOUNT NUMBER(10,2) NOT NULL,
  PAYMENT_REF_NUMBER VARCHAR2(50),
  PAYMENT_DOC BLOB,
  PAYMENT_DOC_FILE_NAME VARCHAR2(50),
  PRIMARY KEY (ID)
)</textarea>
<p>I use NHibernate annotations because I want to have the entity class and the .hbm mapping in the same file.</p>
<p>The idea behind the &#8220;column lazy loading&#8221; hack is to skip mapping the large BLOB column and to red/write it on demand with additional SELECT / UPDATE command.<br />
This approach is applicable to other ORM frameworks that do not support lazy column loading.</p>
<p>Enjoy.</payment>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/11/30/nhibernate-lazy-loading-blob-column/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New Book: Introduction To Programming With C#</title>
		<link>http://www.nakov.com/blog/2009/11/21/new-book-introduction-to-programming-with-csharp/</link>
		<comments>http://www.nakov.com/blog/2009/11/21/new-book-introduction-to-programming-with-csharp/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 23:46:12 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/11/21/new-book-introduction-to-programming-with-c/</guid>
		<description><![CDATA[Today I with Vesko Kolev started a new project: writing a C# book in Bulgarian for beginners that covers the fundamental concepts of computer programming, data structures and algorithms as well as object-oriented concepts, high-quality programming code and problem solving. The book is titled &#8220;Introduction to Programming with C#&#8221; and will be based on its [...]]]></description>
			<content:encoded><![CDATA[<p>Today I with <a href="http://veskokolev.blogspot.com/">Vesko Kolev</a> started a new project: writing a C# book in Bulgarian for beginners that covers the fundamental concepts of computer programming, data structures and algorithms as well as object-oriented concepts, high-quality programming code and problem solving. The book is titled &#8220;Introduction to Programming with C#&#8221; and will be based on its well-known sister, <a href="http://www.introprogramming.info">the book &#8220;Introduction to Programming with Java&#8221;</a>. Most of the book content will be adaptation of its Java variant but some new concepts will also be introduced. The book focuses on the fundamental concepts of computer programming, not just the C# language. It covers topics like recursion, data structures (linear, trees, graphs, hash-tables and sets), combinatorial algorithms and problem solving which can not be found in every C# book. The book does not cover software engineering, Web programming, databases, desktop applications, mobile applications and other software technologies, just the bases of computer programming, logical thinking and problem solving. The book is free and open-source and is driven by volunteers who like to share their knowledge and skills with the young developers who try to make their first steps in computer programming and software engineering.</p>
<p>The book&#8217;s official Web site will be located at: <a href="http://www.introprogramming.info/">http://www.introprogramming.info</a>.</p>
<p>The developer&#8217;s Web site is located in Google Code: <a href="http://code.google.com/p/introcsharpbook/">http://code.google.com/p/introcsharpbook/</a>.</p>
<p>The SVN repository containing all project assets is located at: <a href="http://introcsharpbook.googlecode.com/svn/trunk/">http://introcsharpbook.googlecode.com/svn/trunk/</a>.</p>
<p>The developer&#8217;s mailing list (discussion group) is located at: <a href="http://groups.google.com/group/introcsharpbook">http://groups.google.com/group/introcsharpbook</a>.</p>
<p>Authors and editors are welcome to help the project. To join to this open-source voluntary project please contact Svetlin Nakov or Vesko Kolev. The working language is Bulgarian (some day we plan to publish an English version but let&#8217;s do the things step-by-step).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/11/21/new-book-introduction-to-programming-with-csharp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Playing with the Scanner with WIA and C#</title>
		<link>http://www.nakov.com/blog/2009/11/17/playing-with-the-scanner-with-wia-and-c/</link>
		<comments>http://www.nakov.com/blog/2009/11/17/playing-with-the-scanner-with-wia-and-c/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 22:36:11 +0000</pubDate>
		<dc:creator>nakov</dc:creator>
		
		<category><![CDATA[.net]]></category>

		<category><![CDATA[news]]></category>

		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://www.nakov.com/blog/2009/11/17/playing-with-the-scanner-with-wia-and-c/</guid>
		<description><![CDATA[Last week I needed to implement a piece of software for scanning small documents (bank payment orders). The problem was to scan documents with specific size (less than A4) in 300 DPI and with normal brightness and contrast. I found that in C# there are two general approaches to this problem:

Using the TWAIN interface
Using Windows [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I needed to implement a piece of software for scanning small documents (bank payment orders). The problem was to scan documents with specific size (less than A4) in 300 DPI and with normal brightness and contrast. I found that in C# there are two general approaches to this problem:</p>
<ul>
<li>Using the TWAIN interface</li>
<li>Using Windows Image Acquisition (WIA) API</li>
</ul>
<p>Both interfaces are not natively supported in .NET Framework so some kind of wrappers was necessary to be developed. I choose WIA because it was simpler and higher level API with sufficient enough power.</p>
<p>To use WIA you need to download it from Microsoft (it is a COM server, distributed freely): <a href="http://www.microsoft.com/downloads/details.aspx?familyid=a332a77a-01b8-4de6-91c2-b7ea32537e29&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=a332a77a-01b8-4de6-91c2-b7ea32537e29&amp;displaylang=en</a>.</p>
<p>The next step is to add it as COM object reference in Visual Studio (you need a single file called wiaaut.dll that you need to register with regsvr32). Once you add the reference to WIA COM object in Visual Studio, you get the namespace WIA. All you need to scan image is in this namespace. The most important classes are: Device, Item and CommonDialogClass.</p>
<p>I will not get into more details because developers need code and usually read the text only if the code is not working. Am I right? Did you tread this text?</p>
<textarea name="code" class="csharp:nocontrols:nogutter" cols="100" rows="20">
using System;
using System.IO;
using System.Windows.Forms;
using WIA;

namespace PlayingWithTheScanner
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void buttonScan_Click(object sender, EventArgs e)
        {
            CommonDialogClass commonDialogClass = new CommonDialogClass();
            Device scannerDevice = commonDialogClass.ShowSelectDevice(WiaDeviceType.ScannerDeviceType, false, false);
            if (scannerDevice != null)
            {
                Item scannnerItem = scannerDevice.Items[1];
                AdjustScannerSettings(scannnerItem, 300, 0, 0, 1010, 620, 0, 0);
                object scanResult = commonDialogClass.ShowTransfer(scannnerItem, WIA.FormatID.wiaFormatPNG, false);
                if (scanResult != null)
                {
                    ImageFile image = (ImageFile) scanResult;
                    string fileName = Path.GetTempPath() + DateTime.Now.ToString("dd-MM-yyyy-hh-mm-ss-fffffff") + ".png";
                    SaveImageToPNGFile(image, fileName);
                    pictureBoxScannedImage.ImageLocation = fileName;
                }
            }
        }

        private static void AdjustScannerSettings(IItem scannnerItem, int scanResolutionDPI, int scanStartLeftPixel, int scanStartTopPixel,
            int scanWidthPixels, int scanHeightPixels, int brightnessPercents, int contrastPercents)
        {
            const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";
            const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";
            const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";
            const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";
            const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";
            const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";
            const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
            const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
        }

        private static void SetWIAProperty(IProperties properties, object propName, object propValue)
        {
            Property prop = properties.get_Item(ref propName);
            prop.set_Value(ref propValue);
        }

        private static void SaveImageToPNGFile(ImageFile image, string fileName)
        {
            ImageProcess imgProcess = new ImageProcess();
            object convertFilter = "Convert";
            string convertFilterID = imgProcess.FilterInfos.get_Item(ref convertFilter).FilterID;
            imgProcess.Filters.Add(convertFilterID, 0);
            SetWIAProperty(imgProcess.Filters[imgProcess.Filters.Count].Properties, "FormatID", WIA.FormatID.wiaFormatPNG);
            image = imgProcess.Apply(image);
            image.SaveFile(fileName);
        }
    }
}
</textarea>
<p>The above example scans a small area of the page in 300 DPI (color mode), saves the result in PNG format and displays it in a picture box. Download the entire example&#8217;s source code: <a href='/blog/wp-content/uploads/2009/11/playingwiththescanner.zip' title='playingwiththescanner.zip'>playingwiththescanner.zip</a>.</p>
<p>The interface of WIA is really ugly and is not C# friendly, but that&#8217;s the life. Enjoy&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nakov.com/blog/2009/11/17/playing-with-the-scanner-with-wia-and-c/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
