Index: src/ActiveWriter.sln
===================================================================
--- src/ActiveWriter.sln	(revision 721)
+++ src/ActiveWriter.sln	(working copy)
@@ -22,6 +22,7 @@
 		{68116C7F-C1D8-4DDC-9CA9-9DDA35356EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{68116C7F-C1D8-4DDC-9CA9-9DDA35356EC3}.Release|Any CPU.Build.0 = Release|Any CPU
 		{4BC76225-34A0-435A-9382-759300313F51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4BC76225-34A0-435A-9382-759300313F51}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4BC76225-34A0-435A-9382-759300313F51}.Release|Any CPU.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: src/Dsl/Dsl.csproj
===================================================================
--- src/Dsl/Dsl.csproj	(revision 721)
+++ src/Dsl/Dsl.csproj	(working copy)
@@ -320,6 +320,7 @@
     <Compile Include="Rules\ModelPropertyDeletedRule.cs" />
     <Compile Include="Rules\ModelPropertyDeletingRule.cs" />
     <Compile Include="ServerExplorerSupport\ActiveRecordMapping.cs" />
+    <Compile Include="ServerExplorerSupport\FirebirdHelper.cs" />
     <Compile Include="ServerExplorerSupport\DiagramManager.cs" />
     <Compile Include="ServerExplorerSupport\DSRefNavigator.cs" />
     <Compile Include="ServerExplorerSupport\DSRefNode.cs" />
Index: src/Dsl/ServerExplorerSupport/ActiveRecordMapping.cs
===================================================================
--- src/Dsl/ServerExplorerSupport/ActiveRecordMapping.cs	(revision 721)
+++ src/Dsl/ServerExplorerSupport/ActiveRecordMapping.cs	(working copy)
@@ -123,11 +123,14 @@
                             case "MySql.Data.MySqlClient.MySqlConnection":
 								helper = new MySqlHelper(connection);
 								break;
+                            case "FirebirdSql.Data.FirebirdClient.FbConnection":
+                                helper = new FirebirdHelper(connection);
+                                break;
 							default:
 								// TODO: Support other databases with native providers.
 								Log(
 									string.Format(
-                                        @"Failed: ActiveWriter does not support model generation through {0}. Supported providers: System.Data.SqlClient.SqlConnection, System.Data.OracleClient.OracleConnection, Oracle.DataAccess.Client.OracleConnection, MySql.Data.MySqlClient.MySqlConnection. You can help us improve this functionality, though. See http://www.castleproject.org/others/contrib/index.html to access ActiveWriter source code under the contrib repository, and check Dsl\ServerExplorerSupport\IDbHelper.cs for the start.",
+                                        @"Failed: ActiveWriter does not support model generation through {0}. Supported providers: System.Data.SqlClient.SqlConnection, System.Data.OracleClient.OracleConnection, Oracle.DataAccess.Client.OracleConnection, MySql.Data.MySqlClient.MySqlConnection, FirebirdSql.Data.FirebirdClient.FbConnection. You can help us improve this functionality, though. See http://www.castleproject.org/others/contrib/index.html to access ActiveWriter source code under the contrib repository, and check Dsl\ServerExplorerSupport\IDbHelper.cs for the start.",
 										providerType));
 								return;
 						}
Index: src/Dsl/ServerExplorerSupport/FirebirdHelper.cs
===================================================================
--- src/Dsl/ServerExplorerSupport/FirebirdHelper.cs	(revision 0)
+++ src/Dsl/ServerExplorerSupport/FirebirdHelper.cs	(revision 0)
@@ -0,0 +1,356 @@
+// Copyright 2006 Gokhan Altinoren - http://altinoren.com/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Contributed by Roberto Carlos (robertosistemas@hotmail.com)
+
+namespace Altinoren.ActiveWriter.ServerExplorerSupport
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Data;
+
+    internal class FirebirdHelper : IDbHelper
+    {
+        private IDbConnection _connection = null;
+
+        public FirebirdHelper(IDbConnection connection)
+        {
+            Connection = connection;
+        }
+
+        #region IDbHelper Members
+
+        public IDbConnection Connection
+        {
+            get { return _connection; }
+            set { _connection = value; }
+        }
+
+        public List<Column> GetProperties(ModelClass cls)
+        {
+            List<Column> list = new List<Column>();
+
+            IDbCommand command = GetColumnCommand(cls.Table, cls.Schema);
+            using (IDataReader reader = command.ExecuteReader())
+            {
+                while (reader.Read())
+                {
+                    Column column;
+
+                    column = list.Find(delegate(Column col) { return col.Name == reader["COLUMN_NAME"].ToString().Trim(); }
+                        );
+
+                    if (column == null)
+                    {
+                        column = new Column();
+                        column.Name = reader["COLUMN_NAME"].ToString().Trim();
+                        column.Schema = cls.Schema;
+                        column.Table = cls.Table;
+                        column.DataType = string.Concat(reader["DATA_TYPE"].ToString().Trim(), '_', reader["DATA_SUB_TYPE"].ToString().Trim());
+
+                        if (reader["CONSTRAINT_TYPE"] != DBNull.Value)
+                        {
+                            switch (reader["CONSTRAINT_TYPE"].ToString().Trim())
+                            {
+                                case "PRIMARY KEY":
+                                    column.Primary = true;
+                                    column.PrimaryConstraintName = reader["CONSTRAINT_NAME"].ToString().Trim();
+                                    break;
+                                case "FOREIGN KEY":
+                                    column.ForeignConstraints.Add(reader["CONSTRAINT_NAME"].ToString().Trim());
+                                    break;
+                                // Check constraints not supported right now.
+                            }
+                        }
+
+                        column.Nullable = reader["IS_NULLABLE"].ToString() == "1" ? false : true;
+                        column.Identity = reader["IS_IDENTITY"].ToString() == "1" ? true : false;
+
+                        list.Add(column);
+                    }
+                }
+            }
+
+            return list;
+        }
+
+        /// <summary>
+        /// COLUMN_NAME	DATA_TYPE	FIELD_SUB_TYPE	FIELD_SIZE
+        /// CAMPO01	SHORT	0	2
+        /// CAMPO02	LONG	0	4
+        /// CAMPO03	INT64	0	8
+        /// CAMPO04	FLOAT	0	4
+        /// CAMPO05	DOUBLE	0	8
+        /// CAMPO06	INT64	1	8
+        /// CAMPO07	INT64	2	8
+        /// CAMPO08	DATE	0	4
+        /// CAMPO09	TIME	0	4
+        /// CAMPO10	TIMESTAMP	0	8
+        /// CAMPO11	TEXT	0	10
+        /// CAMPO12	VARCHAR	0	10
+        /// CAMPO13	BLOB	0	8
+        /// CAMPO14	BLOB	1	8
+        /// </summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public NHibernateType GetNHibernateType(string type)
+        {
+            switch (type.ToUpperInvariant())
+            {
+                case "SHORT_0":
+                    return NHibernateType.Int16;
+                case "LONG_0":
+                    return NHibernateType.Int32;
+                case "INT64_0": //BIGINIT
+                    return NHibernateType.Int64;
+                case "FLOAT_0":
+                    return NHibernateType.Single;
+                case "DOUBLE_0":
+                    return NHibernateType.Double;
+                case "INT64_1": //Numeric
+                    return NHibernateType.Decimal;
+                case "INT64_2": //Decimal
+                    return NHibernateType.Decimal;
+                case "DATE_0":
+                    return NHibernateType.DateTime;
+                case "TIME_0":
+                    return NHibernateType.TimeSpan;
+                case "TIMESTAMP_0":
+                    return NHibernateType.Timestamp;
+                case "TEXT_0":
+                    return NHibernateType.Char;
+                case "VARCHAR_0":
+                    return NHibernateType.String;
+                case "BLOB_0":
+                    return NHibernateType.BinaryBlob;
+                case "BLOB_1":
+                    return NHibernateType.StringClob;
+            }
+
+            return NHibernateType.String;
+        }
+
+        public List<Relation> GetFKRelations(ModelClass cls)
+        {
+            List<Relation> list = new List<Relation>();
+
+            IDbCommand command = _connection.CreateCommand();
+
+            command.CommandText =
+               string.Format(@"SELECT
+                    FROM_FIELD.rdb$index_name AS CONSTRAINT_NAME,
+                    '{0}' AS TABLE_SCHEMA,
+                    FROM_TABLE.RDB$RELATION_NAME AS TABLE_NAME,
+                    FROM_FIELD.RDB$FIELD_NAME AS COLUMN_NAME,
+                    '{1}' AS REFERENCED_TABLE_SCHEMA,
+                    TO_TABLE.RDB$RELATION_NAME REFERENCED_TABLE_NAME,
+                    TO_FIELD.RDB$FIELD_NAME AS REFERENCED_COLUMN_NAME
+                FROM
+                    RDB$INDICES FROM_TABLE
+                    INNER JOIN RDB$INDEX_SEGMENTS FROM_FIELD ON FROM_FIELD.RDB$INDEX_NAME = FROM_TABLE.RDB$INDEX_NAME
+                    INNER JOIN RDB$INDICES TO_TABLE ON TO_TABLE.RDB$INDEX_NAME = FROM_TABLE.RDB$FOREIGN_KEY
+                    INNER JOIN RDB$INDEX_SEGMENTS TO_FIELD ON TO_TABLE.RDB$INDEX_NAME = TO_FIELD.RDB$INDEX_NAME
+                WHERE
+                    FROM_TABLE.RDB$FOREIGN_KEY IS NOT NULL
+                AND
+                    FROM_TABLE.RDB$RELATION_NAME = '{2}'
+                AND
+                    (TO_TABLE.RDB$RELATION_NAME is not null)
+                AND
+                    (TO_FIELD.RDB$FIELD_NAME is not null)", cls.Schema, cls.Schema, cls.Table);
+
+            //AddSchemaAndTableParams(command, cls.Schema, cls.Table);
+
+            using (IDataReader reader = command.ExecuteReader())
+            {
+                while (reader.Read())
+                {
+                    list.Add(new Relation
+                                 {
+                                     RelationType = RelationType.Unknown,
+                                     RelationName = reader["CONSTRAINT_NAME"].ToString(),
+                                     PrimaryOwner = reader["REFERENCED_TABLE_SCHEMA"].ToString(),
+                                     PrimaryTable = reader["REFERENCED_TABLE_NAME"].ToString(),
+                                     PrimaryColumn = reader["REFERENCED_COLUMN_NAME"].ToString(),
+                                     ForeignOwner = cls.Schema,
+                                     ForeignTable = cls.Table,
+                                     ForeignColumn = reader["COLUMN_NAME"].ToString()
+                                 });
+                }
+            }
+            return list;
+        }
+
+        public List<Relation> GetPKRelations(ModelClass cls)
+        {
+            List<Relation> list = new List<Relation>();
+
+            IDbCommand command = _connection.CreateCommand();
+            command.CommandText =
+               string.Format(@"SELECT
+                    FROM_FIELD.rdb$index_name AS CONSTRAINT_NAME,
+                    '{0}' AS TABLE_SCHEMA,
+                    FROM_TABLE.RDB$RELATION_NAME AS TABLE_NAME,
+                    FROM_FIELD.RDB$FIELD_NAME AS COLUMN_NAME,
+                    '{1}' AS REFERENCED_TABLE_SCHEMA,
+                    TO_TABLE.RDB$RELATION_NAME REFERENCED_TABLE_NAME,
+                    TO_FIELD.RDB$FIELD_NAME AS REFERENCED_COLUMN_NAME
+                FROM
+                    RDB$INDICES FROM_TABLE
+                    INNER JOIN RDB$INDEX_SEGMENTS FROM_FIELD ON FROM_FIELD.RDB$INDEX_NAME = FROM_TABLE.RDB$INDEX_NAME
+                    INNER JOIN RDB$INDICES TO_TABLE ON TO_TABLE.RDB$INDEX_NAME = FROM_TABLE.RDB$FOREIGN_KEY
+                    INNER JOIN RDB$INDEX_SEGMENTS TO_FIELD ON TO_TABLE.RDB$INDEX_NAME = TO_FIELD.RDB$INDEX_NAME
+                WHERE
+                    FROM_TABLE.RDB$FOREIGN_KEY IS NOT NULL
+                AND
+                    FROM_TABLE.RDB$RELATION_NAME = '{2}'
+                AND
+                    (TO_TABLE.RDB$RELATION_NAME is not null)
+                AND
+                    (TO_FIELD.RDB$FIELD_NAME is not null)", cls.Schema, cls.Schema, cls.Table);
+
+            //AddSchemaAndTableParams(command, cls.Schema, cls.Table);
+
+            using (IDataReader reader = command.ExecuteReader())
+            {
+                while (reader.Read())
+                {
+                    list.Add(new Relation
+                                 {
+                                     RelationType = RelationType.Unknown,
+                                     RelationName = reader["CONSTRAINT_NAME"].ToString(),
+                                     PrimaryOwner = cls.Schema,
+                                     PrimaryTable = cls.Table,
+                                     PrimaryColumn = reader["REFERENCED_COLUMN_NAME"].ToString(),
+                                     ForeignOwner = reader["TABLE_SCHEMA"].ToString(),
+                                     ForeignTable = reader["TABLE_NAME"].ToString(),
+                                     ForeignColumn = reader["COLUMN_NAME"].ToString()
+                                 });
+                }
+            }
+            return list;
+        }
+
+        #endregion
+
+        private IDbCommand GetColumnCommand(string table, string owner)
+        {
+            IDbCommand command = _connection.CreateCommand();
+            command.CommandText =
+                string.Format(@"SELECT
+                    '{0}' TABLE_SCHEMA,
+                    rdb$relation_fields.rdb$relation_name TABLE_NAME,
+                    rdb$relation_fields.rdb$field_name COLUMN_NAME,
+                    CASE
+                        WHEN
+                            rdb$types.rdb$type_name = 'VARYING' THEN 'VARCHAR'
+                        ELSE
+                            rdb$types.rdb$type_name
+                    END DATA_TYPE,
+                    COALESCE(rdb$fields.rdb$field_sub_type, 0) DATA_SUB_TYPE,
+                    rdb$fields.rdb$field_length field_size,
+                    CASE
+                        WHEN
+                            COALESCE(rdb$relation_fields.rdb$null_flag,0) = 0 THEN
+                                1
+                        ELSE
+                            0
+                    END is_nullable,
+                    COALESCE((
+                        SELECT
+                            COALESCE(from_table.rdb$unique_flag,0) is_unique_flag
+                        FROM
+                            rdb$indices from_table
+                            INNER JOIN rdb$index_segments from_field ON from_field.rdb$index_name = from_table.rdb$index_name
+                            INNER JOIN rdb$relation_constraints const_tipo ON const_tipo.rdb$constraint_name = from_field.rdb$index_name
+                            AND const_tipo.rdb$constraint_type = 'PRIMARY KEY'
+
+                        WHERE
+                            from_table.rdb$relation_name = rdb$relations.rdb$relation_name
+                        AND
+                            from_field.rdb$field_name = rdb$relation_fields.rdb$field_name
+                    ),0) AS is_identity,
+                    (
+                        SELECT
+                            const_tipo.rdb$constraint_type
+                        FROM
+                            rdb$indices from_table
+                            INNER JOIN rdb$index_segments from_field ON from_field.rdb$index_name = from_table.rdb$index_name
+                            INNER JOIN rdb$relation_constraints const_tipo ON const_tipo.rdb$constraint_name = from_field.rdb$index_name
+                            AND (const_tipo.rdb$constraint_type = 'PRIMARY KEY' or (const_tipo.rdb$constraint_type = 'FOREIGN KEY'))
+                        WHERE
+                            from_table.rdb$relation_name = rdb$relations.rdb$relation_name
+                        AND
+                            from_field.rdb$field_name = rdb$relation_fields.rdb$field_name
+                        ORDER BY
+                            IIF(const_tipo.rdb$constraint_type = 'PRIMARY KEY',0,1)
+                        ROWS
+                            1
+                    ) AS CONSTRAINT_TYPE,
+                    (
+                        SELECT
+                            const_tipo.rdb$constraint_name
+                        FROM
+                            rdb$indices from_table
+                            INNER JOIN rdb$index_segments from_field ON from_field.rdb$index_name = from_table.rdb$index_name
+                            INNER JOIN rdb$relation_constraints const_tipo ON const_tipo.rdb$constraint_name = from_field.rdb$index_name
+                            AND (const_tipo.rdb$constraint_type = 'PRIMARY KEY' or (const_tipo.rdb$constraint_type = 'FOREIGN KEY'))
+                        WHERE
+                            from_table.rdb$relation_name = rdb$relations.rdb$relation_name
+                        AND
+                            from_field.rdb$field_name = rdb$relation_fields.rdb$field_name
+                        ORDER BY
+                            IIF(const_tipo.rdb$constraint_type = 'PRIMARY KEY',0,1)
+                        ROWS
+                            1
+                    ) AS CONSTRAINT_NAME
+                FROM rdb$relations
+                    INNER JOIN rdb$relation_fields ON rdb$relation_fields.rdb$relation_name = rdb$relations.rdb$relation_name
+                    INNER JOIN rdb$fields ON rdb$fields.rdb$field_name = rdb$relation_fields.rdb$field_source
+                    INNER JOIN rdb$types ON ((rdb$fields.rdb$field_type = rdb$types.rdb$type)
+                        AND (rdb$types.rdb$field_name = 'RDB$FIELD_TYPE'))
+                WHERE
+                    ((rdb$relations.rdb$system_flag = 0) OR (rdb$relations.rdb$system_flag IS NULL))
+                AND
+                    (rdb$relations.rdb$view_source IS NULL)
+                AND
+                    (SUBSTRING(rdb$relation_fields.rdb$relation_name FROM 1 FOR 4) <> 'RDB$')
+                AND
+                    (rdb$relation_fields.rdb$relation_name = '{1}')
+                ORDER BY
+                    rdb$relation_fields.rdb$field_position", owner, table);
+
+            //AddSchemaAndTableParams(command, owner, table);
+
+            return command;
+        }
+
+        private void AddSchemaAndTableParams(IDbCommand command, string owner, string table)
+        {
+            IDbDataParameter param1 = command.CreateParameter();
+            param1.DbType = DbType.String;
+            param1.ParameterName = "?schema";
+            param1.Size = 128;
+            param1.Value = owner;
+            command.Parameters.Add(param1);
+
+            IDbDataParameter param2 = command.CreateParameter();
+            param2.DbType = DbType.String;
+            param2.ParameterName = "?table";
+            param2.Size = 128;
+            param2.Value = table;
+            command.Parameters.Add(param2);
+        }
+    }
+}
\ No newline at end of file
