Testing and Validation CNTK models using C#

…continue from the previous post.
Once the model is build and Loss and Validation functions are satisfied our expectation, we need to validate and test the model using the data which was not part of the training data set (unseen data). The model validation is very important because we want to see if our model is trained well,so that can evaluates unseen data approximately same as the training data. Otherwise the model which cannot predict the output is called overfitted model. Overfitting can happen when the model was trained long enough that shows very high performance for the training data set, but for the testing data evaluate bad results.
We will continue with the implementation from the prevision two posts, and implement model validation. After the model is trained, the model and the trainer are passed to the Evaluation method. The evaluation method loads the testing data and calculated the output using passed model. Then it compares calculated (predicted) values with the output from the testing data set and calculated the accuracy. The following source code shows the evaluation implementation.

private static void EvaluateIrisModel(Function ffnn_model, Trainer trainer, DeviceDescriptor device)
    var dataFolder = "Data";//files must be on the same folder as program
    var trainPath = Path.Combine(dataFolder, "testIris_cntk.txt");
    var featureStreamName = "features";
    var labelsStreamName = "label";

    //extract features and label from the model
    var feature = ffnn_model.Arguments[0];
    var label = ffnn_model.Output;

    //stream configuration to distinct features and labels in the file
    var streamConfig = new StreamConfiguration[]
            new StreamConfiguration(featureStreamName, feature.Shape[0]),
            new StreamConfiguration(labelsStreamName, label.Shape[0])

    // prepare testing data
    var testMinibatchSource = MinibatchSource.TextFormatMinibatchSource(
        trainPath, streamConfig, MinibatchSource.InfinitelyRepeat, true);
    var featureStreamInfo = testMinibatchSource.StreamInfo(featureStreamName);
    var labelStreamInfo = testMinibatchSource.StreamInfo(labelsStreamName);

    int batchSize = 20;
    int miscountTotal = 0, totalCount = 20;
    while (true)
        var minibatchData = testMinibatchSource.GetNextMinibatch((uint)batchSize, device);
        if (minibatchData == null || minibatchData.Count == 0)
        totalCount += (int)minibatchData[featureStreamInfo].numberOfSamples;

        // expected labels are in the mini batch data.
        var labelData = minibatchData[labelStreamInfo].data.GetDenseData<float>(label);
        var expectedLabels = labelData.Select(l => l.IndexOf(l.Max())).ToList();

        var inputDataMap = new Dictionary<Variable, Value>() {
            { feature, minibatchData[featureStreamInfo].data }

        var outputDataMap = new Dictionary<Variable, Value>() {
            { label, null }

        ffnn_model.Evaluate(inputDataMap, outputDataMap, device);
        var outputData = outputDataMap[label].GetDenseData<float>(label);
        var actualLabels = outputData.Select(l => l.IndexOf(l.Max())).ToList();

        int misMatches = actualLabels.Zip(expectedLabels, (a, b) => a.Equals(b) ? 0 : 1).Sum();

        miscountTotal += misMatches;
        Console.WriteLine($"Validating Model: Total Samples = {totalCount}, Mis-classify Count = {miscountTotal}");

        if (totalCount >= 20)
    Console.WriteLine($"------TESTING SUMMARY--------");
    float accuracy = (1.0F - miscountTotal / totalCount);
    Console.WriteLine($"Model Accuracy = {accuracy}");


The implemented method is called in the previous Training method.

 EvaluateIrisModel(ffnn_model, trainer, device);

As can be seen the model validation has shown that the model predicts the data with high accuracy, which is shown on the following picture.

This was the latest post in series of blog posts about using Feed forward neural networks to train the Iris data using CNTK and C#.

The full source code for all three samples can be found here.


Train Iris data by Batch using CNTK and C#

In the previous post we have seen how to train NN model by using MinibatchSource. Usually we should use it when we have large amount of data. In case of small amount of the data, all data can be loaded in memory, and all can be passed to each iteration in order to train the model. This blog post will implement this kind of feeding the trainer.
We will reused the previous implementation, so the starting point can be previous source code. For data loading we have to define a new method. The Iris data is stored in text format like the following:

5.1,3.5,1.4,0.2,setosa(1 0 0)
7.0,3.2,4.7,1.4,versicolor(0 1 0)
7.6,3.0,6.6,2.1,virginica(0 0 1)

The output column is encoded to 1-N-1 encoding rule we have seen previously.
The method will read all the data from the file, parse the data and create two float arrays:

  • float[] feature, and
  • float[] label.

As can be seen both arrays are 1D, which means all data will be inserted in 1D, because the CNTK requires so.  Since the data is in 1D array, we should also provide the dimensionality of the data so te CNTK can resolve what values for each features. The following listing shows the loading Iris data in two 1D array returned as tuple.

static (float[], float[]) loadIrisDataset(string filePath, int featureDim, int numClasses)
    var rows = File.ReadAllLines(filePath);
    var features = new List<float>();
    var label = new List<float>();
    for (int i = 1; i < rows.Length; i++)
        var row = rows[i].Split(',');
        var input = new float[featureDim];
        for (int j = 0; j < featureDim; j++)
            input[j] = float.Parse(row[j], CultureInfo.InvariantCulture);
        var output = new float[numClasses];
        for (int k = 0; k < numClasses; k++)
            int oIndex = featureDim + k;
            output[k] = float.Parse(row[oIndex], CultureInfo.InvariantCulture);


    return (features.ToArray(), label.ToArray());

Once the data is loaded we should change very little amount of the previous code in order to implement batching instead of using minibatchSource. At the beginning we provides several variable to define the NN model structure. Then we call the loadIrisDataset, and define xValues and yValues, which we use in order to create feature and label input variables. Then we create dictionary which connect the feature and labels with data values which we will pass to the trainer later.
The next code is the same as in the previous version in order to create NN model, Loss and Evaluation functions, and learning rate.

Then we create loop, for 800 iteration. Once the iteration reaches the maximum value the program outputs the model properties and terminates.
Above said it implemented in the following code.

public static void TrainIriswithBatch(DeviceDescriptor device)
    //data file path
    var iris_data_file = "Data/iris_with_hot_vector.csv";

    //Network definition
    int inputDim = 4;
    int numOutputClasses = 3;
    int numHiddenLayers = 1;
    int hidenLayerDim = 6;
    int sampleSize = 130;

    //load data in to memory
    var dataSet = loadIrisDataset(iris_data_file, inputDim, numOutputClasses);

    // build a NN model
    //define input and output variable
    var xValues = Value.CreateBatch<float>(new NDShape(1, inputDim), dataSet.Item1, device);
    var yValues    = Value.CreateBatch<float>(new NDShape(1, numOutputClasses), dataSet.Item2, device);

    // build a NN model
    //define input and output variable and connecting to the stream configuration
    var feature = Variable.InputVariable(new NDShape(1, inputDim), DataType.Float);
    var label = Variable.InputVariable(new NDShape(1, numOutputClasses), DataType.Float);

    //Combine variables and data in to Dictionary for the training
    var dic = new Dictionary<Variable, Value>();
    dic.Add(feature, xValues);
    dic.Add(label, yValues);

    //Build simple Feed Froward Neural Network model
    // var ffnn_model = CreateMLPClassifier(device, numOutputClasses, hidenLayerDim, feature, classifierName);
    var ffnn_model = createFFNN(feature, numHiddenLayers, hidenLayerDim, numOutputClasses, Activation.Tanh, "IrisNNModel", device);

    //Loss and error functions definition
    var trainingLoss = CNTKLib.CrossEntropyWithSoftmax(new Variable(ffnn_model), label, "lossFunction");
    var classError = CNTKLib.ClassificationError(new Variable(ffnn_model), label, "classificationError");

    // set learning rate for the network
    var learningRatePerSample = new TrainingParameterScheduleDouble(0.001125, 1);

    //define learners for the NN model
    var ll = Learner.SGDLearner(ffnn_model.Parameters(), learningRatePerSample);

    //define trainer based on ffnn_model, loss and error functions , and SGD learner
    var trainer = Trainer.CreateTrainer(ffnn_model, trainingLoss, classError, new Learner[] { ll });

    //Preparation for the iterative learning process
    //used 800 epochs/iterations. Batch size will be the same as sample size since the data set is small
    int epochs = 800;
    int i = 0;
    while (epochs > -1)
        trainer.TrainMinibatch(dic, device);

        //print progress
        printTrainingProgress(trainer, i++, 50);

    //Summary of training
    double acc = Math.Round((1.0 - trainer.PreviousMinibatchEvaluationAverage()) * 100, 2);
    Console.WriteLine($"------TRAINING SUMMARY--------");
    Console.WriteLine($"The model trained with the accuracy {acc}%");

If we run the code, the output will be the same as we got from the previous blog post example:

The full source code with training data can be downloaded

Using SSH Keys for License generation and validation in .NET Applications


This blog post is going to present how can you implement license functionality in your .NET application. Providing license in your .NET application is very challenging because there is no standard procedure for the implementation. You are free to use whatever you want. But be notice, there is no license which is 100% safe and cannot be cracked or bypassed.

For this purpose I have selected the CocoaFob library for registration code generation and verification in Objective-C applications. Mainly the library is for Objective -C based applications, like iQS mobile applications and other OSX based applications.  This is very interesting library but you cannot use it in .NET applications, there is no implementation for .NET Framework.

The library uses DSA to generate registration keys, which is very hard for hackers to produce key generators. The library is also specific because it generates license key in human readable form, when the bytes are converted in to Base32 string to avoid ambiguous characters. It also groups codes in sets of five characters separated by dashes. Also DSA has encryption algorithm generates the license which is different every time because of a random element introduced during the process.

So the License key is produced using a 512-bit DSA key looks like on the following sample:


More information about CocoaFob can be found at GitHub page: https://github.com/glebd/cocoafob

The library is using BouncyCastle.Crypto Nuget package for DSA encryption and decryption.

The library CocoaFob for .NET contains two classes:

  1. LicenseData class which provide License properties which is used in license generation. It an be anything: Name, Product number, email, date of expiration etc.
  2. LicenseGenerator  class which is responsible for encrypting and validating the license.

For this blog post the License data class has the flowing implementation:

public class LicenseData

protected internal string productCode;
protected internal string name;
protected internal string email;

public virtual string toLicenseStringData()
 StringBuilder result = new StringBuilder();
 if (productCode != null)

 //name is mandatory property
 if (name == null)
 throw new System.Exception("name cannot be null");

 if (email != null)
 return result.ToString();

As can be seen from the code snippet above the License data contains username, product key and email address. Also, only name property is mandatory, which means you can generate license key based on the user name only.

Generating the License Key

One we have License data we can process of License key generation. License is generated using DSA encryption which uses SSH private key.  You can generate public and private SSH keys  using any of the available tools, eg. OpenSSH, GitHub bash, …. More information about private and public key generation you can find at this link. Once we have public and private keys we can generate license and validate it. One important thing to remember is that you have to care about your private key. It should always be secure and no one should have access to it.

The public key is used for license validation, and it is usualy packed with the application as a part of the deployment stuff. So the process of generating the license is show on the flowing code snippet:

public string makeLicense(LicenseData licenseData)
     if (!CanMakeLicenses)
       throw new System.InvalidOperationException("The LicenseGenerator cannot make licenses as it was not configured with a private key");
        var dsa = SignerUtilities.GetSigner("SHA1withDSA");
        dsa.Init(true, privateKey);
        string stringData = licenseData.toLicenseStringData();
        byte[] licBytes = Encoding.UTF8.GetBytes(stringData);
        dsa.BlockUpdate(licBytes, 0, licBytes.Length);
        byte[] signed = dsa.GenerateSignature();
        string license = ToLicenseKey(signed);
        return license;
    catch (Exception e)
        throw new LicenseGeneratorException(e);

First the DSA encryption is created based on the publicKey we have provided as an argument. Then licBytes is generated from the License data, and converted in to UTF8 formatted bytes. Then we have update DSA provider with licBytes. Now the DSA provider can generate signature in bytes. The signature is converted in to LicenseKey by calling ToLicenseKey method. The method is shown on the following code snippet:

private string ToLicenseKey(byte[] signature)
    /* base 32 encode the signature */
    var result = Base32.ToString(signature);

    /* replace O with 8 and I with 9 */
    result = result.Replace("O", "8").Replace("I", "9");

    /* remove padding if any. */
    result = result.Replace("=", "");

    /* chunk with dashes */
    result = split(result, 5);
    return result;

The magic happen in this method during the conversion of signature from bytes to human readable string. Conversion is done using Base32 string helper method.

Verify the License Key

The License verification process is defined in varifyLicense method. You have to provide SSH publicKey as well as

public virtual bool verifyLicense(LicenseData licenseData, string license)
	if (!CanVerifyLicenses)
		throw new System.InvalidOperationException("The LicenseGenerator cannot verify licenses as it was not configured with a public key");
        //Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
        var dsa = SignerUtilities.GetSigner("SHA1withDSA");
        dsa.Init(false, publicKey);

        string stringData = licenseData.toLicenseStringData();
        byte[] msgBytes = Encoding.UTF8.GetBytes(stringData);
        dsa.BlockUpdate(msgBytes, 0, msgBytes.Length);

        var dec = FromLicenseKey(license);
        var retVal = dsa.VerifySignature(dec);
        return retVal; 
    catch (Exception e)
        throw new LicenseGeneratorException(e);

As can be seen from the code above, the validation process is done by generating licenseData, converting the license Key in to signatere and the validation process return true is the license is valid, otherwize return false.

The whole project is published at git hub, an can be downloaded from http://github.com/bhrnjica/cocoafob


Testing the Library

The Library solution contains unit test project which you can see how to use this library in the real scenario in order to implement licensing in .NET app.

Happy programming!

Silverlight 4 Business Application Part 3 of n

Implementation of the Login Dialog in Silverlight application by using MVVM pattern

imageIn the third article, of the series of the Silvelright Business application development, I will present Login dialog implementation by applying  MVVM pattern. Problems looks very simple but if you want to implement in MVVM fashion you could encounter some problems. MVVM pattern became very popular in Silverlight and WPF application development and it seams to be standard development pattern. More information about the pattern can be found on various blogs, internet sites and forums.  One of the first and the best article about MVVM patern is MSND article about MVVM patern by Josh Smith and it can be found here.

This tutorial assume that you know basic principles of the MVVM pattern as well as Silverlight application.

In tis tutorial we will use the MVVM toolkit the implementation of the MVVM pattern developed by Laurent Bugnion, which you can download at http://mvvmlight.codeplex.com/. Before we start the tutorial, download the toolkit and install it as it decribed on the codeplex site.

The idea of the Login dialog, presented here, not depends of the MVVM light toolkit, so it can be easily implemented with other MVVM pattern, like PRISM and others.

Start Visual Studio 2010, and select File->New –>Project, select Silverlight Application in the same way we implemented in Part 2. Instead of Silverlight Aplication, select MvvmLight (SL4) template as picture below shows. After we choose the template, and click OK, Visual Studio designer created Silverlight application which support MVVM pattern.

The picture below shows The New Project dialog window:


As you can see Visual Studio created Silverlight application, but not the ASP.NET web application project. For this tutorial we don’t need it.


The picture above shows project files and how files are arranged in the project. The folder ViewModel contains the ViewModels implementations. Lets create View folder, it will contain Views implementation.

Implementation of MainView and MainViewModel

MainViewContent will be our main content for the Silverlight application. It will be shown after we logged in.

1. Right Click on the recently created View folder, and choose Add->New Item

2. Select Silverlight User Control and give it name MainViewContent.xaml


3. In the XAML file put the following code:

<Grid x:Name="LayoutRoot" Background="White">
                   FontSize="16" FontFamily="Arial Black" />

Implementation is simple. Just TextBlox with some text.

Now we need to create MainViewModelContent:

4. Right Click on the ViewModel folder, and choose Add->New Class

5. Name it MainViewModelContent.cs

Implementation of the MainViewModelContent is in the following listing:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using GalaSoft.MvvmLight;

namespace SLPart3MvvmLoginDialog.ViewModel
    public class MainViewModelContent : ViewModelBase


The implementation is empty cause we want the empty view model without interaction with the view .

Implementation of LoginView and LoginViewModel

Similar as previous we create LoginView.Xaml and LoginViewModel.cs.

Xaml implementation of the LoginView contains controls and layout depicted in the first picture of the article. Here is the main xaml code:

<Border BorderThickness="1" BorderBrush="Black">
        <Grid x:Name="LayoutRoot1" Background="White">
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="*" />
                <RowDefinition Height="40" />
                <RowDefinition Height="30" />
                <RowDefinition Height="28" />
                <RowDefinition Height="28" />
                <RowDefinition Height="40" />
                <RowDefinition Height="28" />
                <RowDefinition Height="*" />

            <Rectangle x:Name="rectangle1" Stroke="Black" StrokeThickness="1" Fill="#FFDE8836" Grid.ColumnSpan="4" />
            <TextBlock Grid.Row="2" x:Name="textBlock2" Text="User Name:" Padding="5" HorizontalAlignment="Right"
                       VerticalAlignment="Center" Grid.Column="1" Margin="0,9" />
            <TextBlock x:Name="textBlock3" Text="Password:" Grid.Row="3" Padding="5" HorizontalAlignment="Right"
                       VerticalAlignment="Center" Grid.Column="1" Margin="0,9" />
            <TextBox Grid.Column="2" Grid.Row="2" x:Name="textBox1" Margin="2" Text="{Binding UserName, Mode=TwoWay}" />
            <PasswordBox Grid.Column="2" Grid.Row="3" x:Name="passwordBox1" Margin="2"  Password="{Binding Password, Mode=TwoWay}"/>

            <Button Content="Cancel" Grid.Column="1" Grid.Row="5" x:Name="radButton1" Margin="5,2" />
            <Button Content="Login" x:Name="radButton2" Grid.Column="2" Grid.Row="5" Margin="5,2" >
                    <i:EventTrigger EventName="Click">
                        <mvvmcmd:EventToCommand Command="{Binding LoginCommand, Mode=OneWay}"
                                CommandParameter="{Binding Main, Source={StaticResource Locator}}"/>
            <TextBlock x:Name="textBlock1" Text="Login Dialog" VerticalAlignment="Center" HorizontalAlignment="Center"
                       Grid.ColumnSpan="2" Margin="10,5,5,12" Grid.Column="1" FontFamily="Portable User Interface"
                       FontSize="20" FontStretch="SemiCondensed" FontWeight="SemiBold" Foreground="Black"/>

The main part of this xaml code above is that the MainViewModel is passed as a parameter of the Login button EventToCommand, and if the login is correct, the LoginModelView change IsLoggedIn property to true. Then main page switch the visibility property of the LoginView to Collapsed, and MainContentView to Visible.

Implementation of the LoginViewModel.cs is show on the next listing:

public LoginViewModel()
    this.LoginCommand = new RelayCommand<object>(this.OnLogging, this.CanLogging);
//Wnen the user click Login button in LoginView
private void OnLogging(object arg)
   var vm = arg as MainViewModel;
   if (vm == null)

   //proces of logging
   vm.IsLogged = true;

private bool CanLogging(object arg)

     return true;

ModelView coresponding classes is always derived from the ModelViewBase.

Putting all together in MainPage and ManViewModel

Now, when you implemented Login  and MainContent, we need put these objects in to MainPage. The MainPage is responsible of showing and hiding these views.

Implementation of the MainPage.xaml

<Grid x:Name="LayoutRoot">

        <my:MainViewContent Visibility="{Binding Main.IsLogged,
                      Converter={StaticResource MainPageBoolLoginToVisibilityConverter1},
                      Source={StaticResource Locator}}"/>
            <my:LoginView Visibility="{Binding Main.IsLogged,
            Converter={StaticResource MainPageBoolLoginToVisibilityConverter1},
            Source={StaticResource Locator}}" HorizontalAlignment="Center" VerticalAlignment="Center" />

Implementation of the MainViewModel

public const string IsLoggedPropertyName = "IsLogged";
private bool _islogged;
public bool IsLogged
      return _islogged;
      if (value != _islogged)
        _islogged = value;

public MainViewModel()
    if (IsInDesignMode)
     // Code runs in Blend --> create design time data.
     // Code runs "for real"

As you can see we implemented IsLogged property, which is the switch between Login and MainViewContent. With BoolToVisibilityConverter class, we were implemented changing visibility of the Views. The converter class is in the source code of the project attached with this tutorial.
Now at the end we have to implement LoginVieModel and MainContentViewModel in to Locator class.
The implementation is very simple and you can see it in the sourcecode project. Now run the application and clik the Login button, The MainContentView appears.


This article present the simple technique you can easily implement in your Silverlight application with full fashion of the MVVM pattern.

The source code can be download from  here.

Silverlight 4 Business Application Part 1 of n

Logins, Users, Roles, Page Content

Currently I am trying to learn Silverlight Business Application development, and during this phase I will try to post some interesting tips and tricks on which I will encounter. I hope you will find some of a code usefull.

In this post I will show how to create starting silverlight business application skeleton, and how you can manipulate with users, roles and content within Silverlight application. As you already know, Silverlight BA uses ASP.NET database model in order to display or hide business data via RIA Services. So, if you want to develop SL application with several modules and each module can access different set of users, you need to handle with users and rolls similar as in ASP.NET application. In this post we will make demo with three pages. Each page will be opened with different users, and admin can open all pages. The screenshot below shows the SL application.

So lets start VS 2010, and choose File New Project, and in list choose Silverlight Business Application see picture below:

Name the new project SLBAPart1 and choose OK button. The VS designer will do a lot of works for us in order to generate starter business application. VS designer generated the two page, completed login and user registration logic as well as database and RIA services. We will add another page called Product, and implementi another link button in mainpage.xaml (see picture below).

  1. To create the new Product.xaml page, right click on Views folder, and choose Add new item
  2. In opened dialog choose Silverlight Page name it Product and click OK.
  3. Add xaml code as depicted on the picture above.

When you run the application you can see the application similar as the first picture shows, which you can access all three pages. There is also “login” link button wich you can login as well as register a new user for SL application.

To define user membership in SL application, select SLBAPart1.Web project  and choose menu ASP.NET Configuration from the Project menu of Visual Studio 2010. Internet Explorer page shows content similar like picture below. Choose Security link button, and click on Creates and Manages roles. Define four roles like picture shows below.

Click Back button and create four users with corresponding roles. The final result of user defining is shown on picture below.

Each user has its own corresponding roles. When you use the attached sample pasword for each user is defined similar as for the first user “$user1user1“. Password for admin user is “$adminadmin“.

After we defined roles and users it is time to define content for each page. Open Product.xaml page from Visual Vtudio project, define content like picture below.

We have to define Public.xaml page which can be accessed if we not logged in. Similar to previous page creation define Public.xaml page, and put some text in it.

Next step in implementation is  prevent user to see content if it is not authorized. To implement that, we need to expand ContentFrame_Navigated event of the mainpage.xaml.cs.

private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
     //Check to see if user has right to navigate
     if (!UserCanNavigate(e))

     foreach (UIElement child in LinksStackPanel.Children)
         HyperlinkButton hb = child as HyperlinkButton;
         if (hb != null && hb.NavigateUri != null)
            if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
                VisualStateManager.GoToState(hb, "ActiveLink", true);
               VisualStateManager.GoToState(hb, "InactiveLink", true);

When the user click for content ContentFrame_Navigated event fires up. Then UserCanNavigate method gets call. The implementation of this method is the following:

private bool UserCanNavigate(NavigationEventArgs sender)
    //if user is not authenticated show public content
    if (!WebContext.Current.User.IsAuthenticated)
        ContentFrame.Source = new System.Uri("/Public", UriKind.RelativeOrAbsolute);
        return false;
    } //If the user is loged show only content on which is authorizated
        //If user is admin alow everithing
            return true;
        //if user is in rol1 open Home content
        if (WebContext.Current.User.IsInRole("Rol1"))
            ContentFrame.Source = new System.Uri("/Home", UriKind.RelativeOrAbsolute);
            return false;
        }//Similar to previous
        if (WebContext.Current.User.IsInRole("Rol2"))
            ContentFrame.Source = new System.Uri("/About", UriKind.RelativeOrAbsolute);
            return false;
            ContentFrame.Source = new System.Uri("/Product", UriKind.RelativeOrAbsolute);
            return false;


Build application and run. The picture below shows our application. If we try to navigate to any content before we LogedIn we always get the same public content. Depending on user information when we logged in ,we get coresponding content.

Thats all for now. We learned how we can manipulate with content and different user roles. Source code for this demo can be downloaded from here.