Tuesday, August 16, 2011

Encrypting all the Stored Procedures of a Database

If you ever decide that you need to protect your SQL Stored Procedures, and thought encrypting was a good idea, BE VERY CAREFUL!!!



Encrypting Database stored procedures SHOULD NOT be done without having backup files or some sort of Source Control for the stored procedures. The reason I say this is because, once they are encrypted, there is no turning around. (Yes, there are third party tools that will decrypt your code, but Why go through that trouble.)



This trick is something I developed because my company needed to host the application on a different server, and we were concerned about our code being compromised. So, to deliver the database, we decided to encrypt all out stored procedures. Having over a hundred procedures written, I didn't want to open each procedure and paste 'WITH ENCRYPTION' in each and every stored procedure. (For those of you who do not know how to encrypt, refer How Do I Protect My Stored Procedure Code[^]). So I decided to make my own little C# application that did the same.




This application is a console application made using Visual Studio 2005 and SQL server 2005. The input parameters are database name, Server address, database username and password. Once you are able to provide these details, you are ready to have all your stored procedures encrypted.



I have put the code of my application here as is. For this code to work, you will need to add an "Microsft.SQlserver.SMO" refrence to the application, so that the classes such as "Database" and "StoredProcedure" are accessible.



BEFORE YOU DO THIS, TAKE A BACKUP!!!!!!!



//Connect to the local, default instance of SQL Server. 
string DB = "";
ServerConnection objServerCOnnection = new ServerConnection();
objServerCOnnection.LoginSecure = false;
Console.WriteLine("Enter name or IP Address of the Database Server.");            
objServerCOnnection.ServerInstance = Console.ReadLine();
Console.WriteLine("Enter name of the Database");
DB = Console.ReadLine();
Console.WriteLine("Enter user id");
objServerCOnnection.Login = Console.ReadLine();
Console.WriteLine("Enter Password");
objServerCOnnection.Password = Console.ReadLine();
Console.WriteLine(" ");
Server srv = new Server();

try // Check to see if server connection details are ok.
{
   srv = new Server(objServerCOnnection);
   if (srv == null)
   {
      Console.WriteLine("Server details entered are wrong,"

         + " Please restart the application");
      Console.ReadLine();
      System.Environment.Exit(System.Environment.ExitCode);
   }
}
catch
{
   Console.WriteLine("Server details entered are wrong,"
      + " Please restart the application");
   Console.ReadLine();
   System.Environment.Exit(System.Environment.ExitCode);
}
Database db = new Database();

try // Check to see if database exists.
{
   db = srv.Databases[DB];
   if (db == null)
   {
      Console.WriteLine("Database does not exist on the current server,"
         + " Please restart the application");
      Console.ReadLine();
      System.Environment.Exit(System.Environment.ExitCode);
   }
}

catch
{
   Console.WriteLine("Database does not exist on the current server,"
      + " Please restart the application");
   Console.ReadLine();
   System.Environment.Exit(System.Environment.ExitCode);
}
string allSP = "";
                

for (int i = 0; i < db.StoredProcedures.Count; i++)
{
   //Define a StoredProcedure object variable by supplying the parent database 
   //and name arguments in the constructor. 
   StoredProcedure sp;
   sp = new StoredProcedure();
   sp = db.StoredProcedures[i];
   if (!sp.IsSystemObject)// Exclude System stored procedures

   {
      if (!sp.IsEncrypted) // Exclude already encrypted stored procedures
      {
         string text = "";// = sp.TextBody;

         sp.TextMode = false;
         sp.IsEncrypted = true;
         sp.TextMode = true;
         sp.Alter();
 
         Console.WriteLine(sp.Name); // display name of the encrypted SP.                        
         sp = null;
         text = null;
      }
   }
}

Monday, August 15, 2011

The Biggest Changes in C++11


The Biggest Changes in C++11 (and Why You Should Care)






It’s been 13 years since the first iteration of the C++ language. Danny Kalev, a former member of the C++ standards committee, explains how the programming language has been improved and how it can help you write better code.



Bjarne Stroustrup, the creator of C++, said recently that C++11 “feels like a new language — the pieces just fit together better.” Indeed, core C++11 has changed significantly. It now supports lambda expressions, automatic type deduction of objects, uniform initialization syntax, delegating constructors, deleted and defaulted function declarations, nullptr, and most importantly, rvalue references — a feature that augurs a paradigm shift in how one conceives and handles objects. And that’s just a sample.
The C++11 Standard Library was also revamped with new algorithms, new container classes, atomic operations, type traits, regular expressions, new smart pointers, async() facility, and of course a multithreading library.
A complete list of the new core and library features of C++11 is available here.
After the approval of the C++ standard in 1998, two committee members prophesied that the next C++ standard would “certainly” include a built-in garbage collector (GC), and that it probably wouldn’t support multithreading because of the technical complexities involved in defining a portable threading model. Thirteen years later, the new C++ standard, C++11, is almost complete. Guess what? It lacks a GC but it does include a state-of–the-art threading library.
In this article I explain the biggest changes in the language, and why they are such a big deal. As you’ll see, threading libraries are not the only change. The new standard builds on the decades of expertise and makes C++ even more relevant. As Rogers Cadenhead points out, “That’s pretty amazing for something as old as disco, Pet Rocks, and Olympic swimmers with chest hair.”
First, let’s look at some of the prominent C++11 core-language features.

Lambda Expressions

A lambda expression lets you define functions locally, at the place of the call, thereby eliminating much of the tedium and security risks that function objects incur. A lambda expression has the form:
[capture](parameters)->return-type {body}
The [] construct inside a function call’s argument list indicates the beginning of a lambda expression. Let’s see a lambda example.
Suppose you want to count how many uppercase letters a string contains. Using for_each() to traverses a char array, the following lambda expression determines whether each letter is in uppercase. For every uppercase letter it finds, the lambda expression increments Uppercase, a variable defined outside the lambda expression:
int main()
{
   char s[]="Hello World!";
   int Uppercase = 0; //modified by the lambda
   for_each(s, s+sizeof(s), [&Uppercase] (char c) {
    if (isupper(c))
     Uppercase++;
    });
 cout<< Uppercase<<" uppercase letters in: "<< s<
It’s as if you defined a function whose body is placed inside another function call. The ampersand in [&Uppercase] means that the lambda body gets a reference to Uppercase so it can modify it. Without the ampersand, Uppercase would be passed by value. C++11 lambdas include constructs for member functions as well.

Automatic Type Deduction and decltype

In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object’s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:
auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long
Automatic type deduction is chiefly useful when the type of the object is verbose or when it’s automatically generated (in templates). Consider:
void func(const vector &vi)
{
vector::const_iterator ci=vi.begin();
}
Instead, you can declare the iterator like this:
auto ci=vi.begin();
The keyword auto isn’t new; it actually dates back the pre-ANSI C era. However, C++11 has changed its meaning; auto no longer designates an object with automatic storage type. Rather, it declares an object whose type is deducible from its initializer. The old meaning of auto was removed from C++11 to avoid confusion.
C++11 offers a similar mechanism for capturing the type of an object or an expression. The new operator decltype takes an expression and “returns” its type:
const vector vi;
typedef decltype (vi.begin()) CIT;
CIT another_const_iterator;

Uniform Initialization Syntax

C++ has at least four different initialization notations, some of which overlap.
Parenthesized initialization looks like this:
std::string s("hello");
int m=int(); //default initialization
You can also use the = notation for the same purpose in certain cases:
std::string s="hello";
int x=5;
For POD aggregates, you use braces:
int arr[4]={0,1,2,3};
struct tm today={0};
Finally, constructors use member initializers:
struct S {
 int x;
 S(): x(0) {} };
This proliferation is a fertile source for confusion, not only among novices. Worse yet, in C++03 you can’t initialize POD array members and POD arrays allocated using new[]. C++11 cleans up this mess with a uniform brace notation:
class C
{
int a;
int b;
public:
 C(int i, int j);
};

C c {0,0}; //C++11 only. Equivalent to: C c(0,0);

int* a = new int[3] { 1, 2, 0 }; /C++11 only

class X {
  int a[4];
public:
  X() : a{1,2,3,4} {} //C++11, member array initializer
};
With respect to containers, you can say goodbye to a long list of push_back() calls. In C++11 you can initialize containers intuitively:
// C++11 container initializer
vector vs={ "first", "second", "third"};
map singers =
  { {"Lady Gaga", "            +1 (212) 555-7890      "},
    {"Beyonce Knowles", "            +1 (212) 555-0987      "}};
Similarly, C++11 supports in-class initialization of data members:
class C
{
 int a=7; //C++11 only
public:
 C();
};

Deleted and Defaulted Functions

A function in the form:
struct A
{
 A()=default; //C++11
 virtual ~A()=default; //C++11
};
is called a defaulted function. The =default; part instructs the compiler to generate the default implementation for the function. Defaulted functions have two advantages: They are more efficient than manual implementations, and they rid the programmer from the chore of defining those functions manually.
The opposite of a defaulted function is a deleted function:
int func()=delete;
Deleted functions are useful for preventing object copying, among the rest. Recall that C++ automatically declares a copy constructor and an assignment operator for classes. To disable copying, declare these two special member functions =delete:
struct NoCopy
{
    NoCopy & operator =( const NoCopy & ) = delete;
    NoCopy ( const NoCopy & ) = delete;
};
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted

nullptr

At last, C++ has a keyword that designates a null pointer constant. nullptr replaces the bug-prone NULL macro and the literal 0 that have been used as null pointer substitutes for many years.nullptr is strongly-typed:
void f(int); //#1
void f(char *);//#2
//C++03
f(0); //which f is called?
//C++11
f(nullptr) //unambiguous, calls #2
nullptr is applicable to all pointer categories, including function pointers and pointers to members:
const char *pc=str.c_str(); //data pointers
if (pc!=nullptr)
  cout<

Delegating Constructors

In C++11 a constructor may call another constructor of the same class:
class M //C++11 delegating constructors
{
 int x, y;
 char *p;
public:
 M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target
 M(): M(0) {cout<<"delegating ctor"<
Constructor #2, the delegating constructor, invokes the target constructor #1.

Rvalue References

Reference types in C++03 can only bind to lvalues. C++11 introduces a new category of reference types called rvalue references. Rvalue references can bind to rvalues, e.g. temporary objects and literals.
The primary reason for adding rvalue references is move semantics. Unlike traditional copying, moving means that a target object pilfers the resources of the source object, leaving the source in an “empty” state. In certain cases where making a copy of an object is both expensive and unnecessary, a move operation can be used instead. To appreciate the performance gains of move semantics, consider string swapping. A naive implementation would look like this:
void naiveswap(string &a, string & b)
{
 string temp = a;
 a=b;
 b=temp;
}
This is expensive. Copying a string entails the allocation of raw memory and copying the characters from the source to the target. In contrast, moving strings merely swaps two data members, without allocating memory, copying char arrays and deleting memory:
void moveswapstr(string& empty, string & filled)
{
//pseudo code, but you get the idea
 size_t sz=empty.size();
 const char *p= empty.data();
//move filled's resources to empty
 empty.setsize(filled.size());
 empty.setdata(filled.data());
//filled becomes empty
 filled.setsize(sz);
 filled.setdata(p);
}
If you’re implementing a class that supports moving, you can declare a move constructor and a move assignment operator like this:
class Movable
{
Movable (Movable&&); //move constructor
Movable&& operator=(Movable&&); //move assignment operator
};
The C++11 Standard Library uses move semantics extensively. Many algorithms and containers are now move-optimized.

C++11 Standard Library

C++ underwent a major facelift in 2003 in the form of the Library Technical Report 1 (TR1). TR1 included new container classes (unordered_set, unordered_map, unordered_multiset, and unordered_multimap) and several new libraries for regular expressions, tuples, function object wrapper and more. With the approval of C++11, TR1 is officially incorporated into standard C++ standard, along with new libraries that have been added since TR1. Here are some of the C++11 Standard Library features:

THREADING LIBRARY

Unquestionably, the most important addition to C++11 from a programmer’s perspective is concurrency. C++11 has a thread class that represents an execution thread, promises and futures, which are objects that are used for synchronization in a concurrent environment, theasync() function template for launching concurrent tasks, and the thread_local storage type for declaring thread-unique data. For a quick tour of the C++11 threading library, read Anthony Williams’ Simpler Multithreading in C++0x.

NEW SMART POINTER CLASSES

C++98 defined only one smart pointer class, auto_ptr, which is now deprecated. C++11 includes new smart pointer classes: shared_ptr and the recently-added unique_ptr. Both are compatible with other Standard Library components, so you can safely store these smart pointers in standard containers and manipulate them with standard algorithms.

NEW ALGORITHMS

The C++11 Standard Library defines new algorithms that mimic the set theory operationsall_of(), any_of() and none_of(). The following listing applies the predicateispositive() to the range [first, first+n) and uses all_of(), any_of() andnone_of() to examine the range's properties:
#include 
//C++11 code
//are all of the elements positive?
all_of(first, first+n, ispositive()); //false
//is there at least one positive element?
any_of(first, first+n, ispositive());//true
// are none of the elements positive?
none_of(first, first+n, ispositive()); //false
A new category of copy_n algorithms is also available. Using copy_n(), copying an array of 5 elements to another array is a cinch:
#include
int source[5]={0,12,34,50,80};
int target[5];
//copy 5 elements from source to target
copy_n(source,5,target);
The algorithm iota() creates a range of sequentially increasing values, as if by assigning an initial value to *first, then incrementing that value using prefix ++. In the following listing,iota() assigns the consecutive values {10,11,12,13,14} to the array arr, and {'a', 'b', 'c'} to the char array c.
include 
int a[5]={0};
char c[3]={0};
iota(a, a+5, 10); //changes a to {10,11,12,13,14}
iota(c, c+3, 'a'); //{'a','b','c'}
C++11 still lacks a few useful libraries such as an XML API, sockets, GUI, reflection — and yes, a proper automated garbage collector. However, it does offer plenty of new features that will make C++ more secure, efficient (yes, even more efficient than it has been thus far! See Google'sbenchmark tests), and easier to learn and use.
If the changes in C++11 seem overwhelming, don't be alarmed. Take the time to digest these changes gradually. At the end of this process you will probably agree with Stroustrup: C++11 doesfeel like a new language — a much better one.

Sunday, August 14, 2011

Bitwise operators in c#

Bitwise operators in c# OR(|), XOR(^), AND(&amp;), NOT(~)

This post is a brush up on some of the bitwise operators that we shall be using for creating bitmasks to set permissions(my next post will be on exactly this subject. Bitmasks).



The c# bitwise operators I shall be covering here and are of particular interest to me in my followup post are :



  1. binary OR(|) operator
  2. binary AND(&) operator
  3. XOR (^) operator
  4. Not (~) operator

Binary OR(|) operator

Binary | operators are predefined for the integral types and bool. For integral types, | computes the bitwise OR of its operands. For bool operands, | computes the logical OR of its operands; that is, the result is false if and only if both its operands are false.
Lets focus on the integral types(types that can be represented as numbers) and how the computation takes place.

protected void Page_Load(object sender, EventArgs e) { byte a = 7; byte b = 9; int orComputed = a | b; Response.Write(string.Format( "<br />{0} | {1} OR computed :{2}",      a, b, orComputed)); }


Output :

7 | 9 Result :15



To understand what just happened we need to look at bits and how each bit(which contains an integral type) is understood by the computer. The computer is going to understand this as binary data in the form of 0's and 1's eg. -->> 00101010(which represents the number 42), this is actaully much easier for a computer to handle since each bit(or integral type as in number), can be interpreted as either on or off signal.



0 = off

1 = on




To understand the bitwise operator with clarity and how it computes the result, lets first construct a base 2 table from right to left incrementing the exponent by 1 for each power. So, since we have 8 bits in a byte, we make a table that lists 8 elements 128, 64, 32, 16, 8, 4, 2, 1.



128 64 32 16 8 4 2 1 Result
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 2
0 0 0 0 0 1 0 0 4
0 0 0 0 1 0 0 0 8
0 0 0 1 0 0 0 0 16
0 0 1 0 0 0 0 0 32
0 1 0 0 0 0 0 0 64
1 0 0 0 0 0 0 0 128


If you will look at the above pattern more closely, we notice how the 1 keeps moving 1 digit to the left for every new value in binary. This is also known as a "bit shift".



Ok, now that we have our binary 8bit table with digits to the power of 2^ up to 128, so for a simple 7 | 9, which yielded the result 15, lets look at how it was computed by first creating the binary representation using our base 2 table and then computing the binary | operation, so :



128 64 32 16 8 4 2 1 Calculation Result
0 0 0 0 0 1 1 1 (4+2+1) 7
0 0 0 0 1 0 0 1 (8+1) 9
0 0 0 0 1 1 1 1 (8+4+2+1) 15


As you can see from the above, binary (|) is being performed on each pair of corresponding bits. If a 1 is present in the either bit or in both bits, otherwise it's 0. Not clear ? Lets try that again. How did we get the result 1111 ? It's a simple comparision. If either bit stacked ontop of one another are 1 or both are 1, then the result is 1, otherwise the result is 0. So 1 on 1 = 1, 1 on 0 = 1 but 0 on 0 = 0.

Binary AND(&) operator

Quoting MSDN Docs :

Binary & operators are predefined for the integral types and bool. For integral types, & computes the logical bitwise AND of its operands. For bool operands, & computes the logical AND of its operands; that is, the result is true if and only if both its operands are true.
So, lets quickly test this :




protected void Page_Load(object sender, EventArgs e) { byte a = 7; byte b = 9; int orComputed = a & b; Response.Write(string.Format( "<br />{0} & {1} Result :{2}",      a, b, orComputed)); }


Output is :

7 & 9 Result :1



Lets convert to binary using our base 2 table, and dig deeper  :




128 64 32 16 8 4 2 1 Calculation Result
0 0 0 0 0 1 1 1 (4+2+1) 7
0 0 0 0 1 0 0 1 (8+1) 9
0 0 0 0 0 0 0 1 (1) 1


so, how did we get the binary result 0001(1) ?  binary (&) is being performed on each pair of corresponding bits. The comparision is made based on both bits stacked ontop of one another. if both are one's, then we have a 1, anything else is a 0. so 1 on 1 = 1, 1 on 0 = 0, 0 on 0 = 0.

Binary Xor (^) operator



Quoting MSDN Docs:

Binary ^ operators are predefined for the integral types and bool. For integral types, ^ computes the bitwise exclusive-OR of its operands. For bool operands, ^ computes the logical exclusive-or of its operands; that is, the result is true if and only if exactly one of its operands is true.
A simple c# example :



protected void Page_Load(object sender, EventArgs e) { sbyte a = 7; sbyte b = 9; int orComputed = a^b;//on a negative Response.Write(string.Format( "<br />{0} ^ {1} Result :{2}",      a,b, orComputed.ToString())); }
output :

7 ^ 9 Result :14



Now, how did binary (^) Xor'ing 7 ^ 9 produce 14 ? This is because binary (^) is being performed on each pair of corresponding bits. If we have two matching zero's or one's, then the result is 0, otherwise 1. SO, 1 on 1 = 0, 0 on 0 = 0, 1 on 0 = 1, 0 on 1 = 1. Lets look at an example in our base 2 table of 7 and 9 in binary format :



128 64 32 16 8 4 2 1 Calculation Result
0 0 0 0 0 1 1 1 (4+2+1) 7
0 0 0 0 1 0 0 1 (8+1) 9
0 0 0 0 1 1 1 0 (8+4+2) 14

Not (~) operator

Quoting MSDN Docs:

The ~ operator performs a bitwise complement operation on its operand, which has the effect of reversing each bit. Bitwise complement operators are predefined for int, uint, long, and ulong.
This is also a unary operator so we don't need to pass a value. Unary operators perform an operation on a single operand eg. ~n and not x~y.

Binary (~) operator is the most confusing one. It performs reversing of each bit, so reversing a positive can produce a negative value. Negative Values Use Two's Complement format and is quite tricky.
A simple example :



protected void Page_Load(object sender, EventArgs e) { sbyte a = 7; int orComputed1 = ~-a;//on a negative int orComputed2 = ~a;// on a positive Response.Write(string.Format( "<br />~-{0} Result :{1}",        a, orComputed1)); Response.Write(string.Format( "<br />~+{0} Result :{1}",        a, orComputed2)); }
output :

~-7 Result :6

~+7 Result :-8



As you can see, when the NOT(~) operator is applied to a positive number, the resulting value is a negative. This is because the value is reversed. Since this reversing yields a negative or positive depending on what value your reversing, use a signed type (a type that can store a negative value).



In the base table below, our binary number gets inverted. all 1's become 0 and 0 becomes 1.



A signed binary uses the left most bit to keep track of the sign(negative or positive).

In the c# compiler, negative values are represented internally in two's complement format. Two's complement can be obtained by negating each bit of the value, then adding 1. Performing two's complement twice generates the original value.




In the following base 2 table, one typical gotcha when inverting is to remember to start the inversion from the left of the first 1 value in our binary. So, say had we a binary representation of the digit 7(00000111), then we start inverting at the 2nd digit starting at the right, skipping the first(since it's 1)  and get 11111001. A last thing to also note is how in our calculation we added a negative -1 to our result instead of a positive 1 -->> (-128+64+32+16+8+1)-1 ; While the two's complement format states that we need add 1, we are actually deducting 1 versus adding 1. This is because we have to consider 0 in the equation.



An easy method to get the two's complement of +7 :(left most is used to track sign, so add -1 to the result) :



128 64 32 16 8 4 2 1 Calculation Result
0 0 0 0 0 1 1 1 (4+2+1) 7
1 1 1 1 1 0 0 1 (-128+64+32+16+8+1)-1 -8


Note the left most significant pair of corresponding bits in red. A value of 0 means positive and a value of 1 means negative and is used for tracking the sign in a signed binary.



One question still remains, why is the two's complement always a positive less(6) and a negative more(-8) ?

Why aren't we getting -7 for a 7 and vice versa. I guess the answer to this is simply "logic", we have to consider the 0.



-8 -7 -6 -5 -4 -3 -2 -1
7 6 5 4 3 2 1 0

Monday, August 8, 2011

Removing Unused Css form classes from your web application


Most of you might have seen that while working on a Website project, the CSS gets harder to maintain as the site ages. This might be due to new developers coming in to the project, removal of UI elements (but not the corresponding CSS), refactoring and so on. I think it is a good idea to revisit and clean your css every few weeks before it becomes totally unmanageable. In this post, i am going to outline 2 ways to do so
There is a great Firefox plugin called Dust-Me Selectors which can test individual web pages or spider your Website to find unused CSS selectors. As you navigate from page to page in your Website, it maintains a list of unused CSS selectors that you can remove.
If for some reason you cannot use the plugin, or would like to be more sure, I have also created a small utility (for personal use) that can parse a CSS file to create a list of defined classes and go through the code base to determine which of those classes are actually being used. This utility usually gives me a list of unused CSS classes with an accuracy of greater than 95%. It cannot give a 100% accurate output in cases where the css classes are being assigned dynamically in JavaScript or server side code (it catches some of them, but not all). But it gives you a great starting point. I normally search my codebase for the CSS class name before commenting it out from the CSS file to be sure its not being used in the code anywhere. I delete the commented out CSS classes after a couple of releases if I do not see any issues.
You can download the utility (named CssCleaner) from here. Please remember that this does not come with any kind of warranty, I am just sharing this so that it can be helpful to somebody in a situation similar to mine.
CssCleaner is pretty simple to use. Download the app, unzip it to a folder on your system. You should see 2 files – CssCleaner.exe and CssCleaner.exe.config. The config file is needed by the application and is present to make a couple of things configurable. I’ll talk more about it in a second.

After you run the application, click on "Choose Application Folder" and choose the code base folder for your Website. Click on "Choose CSS File" and select the CSS file that you want to analyze. Change the File Filter if you would like to process files different from the default types. Leaving that textbox blank processes all files. Click on "Process" to run the utility. The unused classes get loaded on the right hand side. In my use, the tool has been pretty fast.
If anybody is interested in the implementation, i use a parser/scanner to parse the CSS file similar to this. Then I go through all the files in the code base, building a list of  used CSS classes using a regular expression. The regular expression is picked up from the config file, so you can tweak it as you find suitable. The other thing picked up from the config file is the list of default file types to search for. It then compares the used CSS class list against the available CSS classes and displays the unused classes list.
If you have any suggestions for the tool, or find any bugs, please leave a comment or email me (latish.sehgal at gmail dot com) and I’ll try my best to implement it. I hope that you find this tool helpful.