text:
[Back to README](../README.md)

## Front end Technology

The dashboard front end is primary built using React.js and Flux written in Coffeescript. What follows is an overview of how data moves through the app and some more general resources for understanding the stack.

### Resources
- [Thinking in React](https://facebook.github.io/react/docs/thinking-in-react.html)
- [Flux: Actions and the Dispatcher](https://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html) - Note that the dispatcher is abstracted away in [McFly](https://github.com/kenwheeler/mcfly), the Flux implementation used on the Dashboard.
- [React DnD](http://gaearon.github.io/react-dnd/) - The library used for drag-and-drop interactions on the timeline

### Actions
Actions are exactly what they sound like: any impactful front end user action should trigger a Flux action that can be received and acted upon by a store. Think of a Flux action as being similar to an emitted event.

##### ServerActions
ServerActions define a set of actions that interact with the Rails application via AJAX requests. Notably, several ServerActions are triggered by default when a course page is first loaded. These Actions trigger AJAX requests through the API helper and use a promise to emit an event for subscribed Stores when the AJAX request returns.

### Stores
Stores listen for Actions and are responsible for parsing, storing, and providing application data to all components. They can subscribe to any action and they can also emit a change event that is received by all subscribed components.

##### StockStore
StockStore is store factory that returns a Store implementing a set of features used by several different models in the Dashboard application. These include:

- Object CRUD
- Object filtering by key
- Object sorting by key
- Data persistence (user actions can be cancelled and changes reverted)
- Load state tracking (whether or not the store has received data from the server)

### Components
Components are the view layer of the JS application. They contain HTML markup and methods that trigger Actions based on user input.

##### High-order components
[High-order components](/app/assets/javascripts/components/high_order) are essentially wrappers for passed components. [This post](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) describes the idea very well. They are not polymorphic classes, they are a replacement for mixins. That is, they provide reusable methods or rendering patterns to the components that they wrap without violating idiomatic React (as mixins do).

The [Conditional component](/app/assets/javascripts/components/high_order/conditional.cjsx) is a simple example: it contains all of the logic for conditionally rendering a component based on a boolean prop. This means we can make any component render based on a boolean without repeating that logic. For example, adding this functionality to the Select component is as simple as changing

	module.exports = Select
to

	module.exports = Conditional(Select)

and passing a `show` parameter to any Select used in our application.

##### Common components
Common components are utilities used throughout the application. These include inputs and modals, among others. They are not special components, they just don't belong to a specific part of the application.

### Utils
Utils include several different helpers for our application and two of them are worth an explanation.

#### Router
The [router.cjsx](/app/assets/javascripts/utils/router.cjsx) file contains an implementation of [React Router](https://github.com/rackt/react-router). Here we define handlers for different URL paths and structure a hierarchy that allows components to optionally wrap other components based on the URL. As of this writing the React Router library is undergoing some big restructuring for a 1.0 push but documentation for the current version [can be found here](http://rackt.github.io/react-router/).

#### API
The [api.coffee](/app/assets/javascripts/utils/api.coffee) file contains all AJAX requests for the application. Many methods are named according to their  purpose excepting the `fetch` and `modify` methods. These are written to be widely reused by `ServerActions` and require some extra hand-holding to ensure that the proper endpoint is reached.

## NPM Shrinkwrap
When dependencies need to be updated, do so using the `--save` flag. With `npm v3.x`, it will automatically update the shrinkwrap file. If that fails for some reason, you can manually run `npm shrinkwrap` once your dependencies are fixed.

E.g., `npm install react@15.0.0 --save` will install a specific version, save it to your package.json, and update the shrinkwrap file.


text:
<!DOCTYPE html>

	<meta charset="utf-8">
	<title>DocStrap tutorialDrive Car</title>

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.cerulean.css">

			DocStrap

					Namespaces

							teams

					Modules

							docstrap/car

							docstrap/person

					Classes

							Car

							Person

					Mixins

							insanity

					Events

							sneeze

					Tutorials

							Brush Teeth

							Drive Car

							Fence Test

					Global

							brakeBias

							drift

							start

							trailBrake

Drive Car

Lorem ipsum dolor sit amet

Curabitur est mi, fermentum lacinia tincidunt vitae, mattis sit amet neque. Quisque diam nisl, accumsan ac porta tincidunt, iaculis facilisis ipsum. Nulla facilisi. Aenean a metus tortor. Pellentesque congue, mauris vitae viverra varius, elit nunc dictum nisl, rhoncus ultrices nulla sapien at leo. Duis ultricies porttitor diam. Nulla facilisi. Nullam elementum, lorem eu imperdiet laoreet, est turpis sollicitudin velit, in porttitor justo dolor vel urna. Mauris in ante magna. Curabitur vitae lacus in magna mollis commodo.

Fusce lacinia, mauris ac aliquam consequat

Fusce molestie blandit velit, sit amet dictum eros pharetra vitae. In erat urna, condimentum ac feugiat id, rutrum et nisi. Cras ac velit lorem. Nulla facilisi. Maecenas dignissim nulla in turpis tempus sed rhoncus augue dapibus. Nulla feugiat, urna non sagittis laoreet, dolor metus rhoncus justo, sed semper ante lacus eget quam. Sed ac ligula magna. Sed tincidunt pulvinar neque in porta. Nullam quis lacus orci. Pellentesque ornare viverra lacus, id aliquam magna venenatis a.

Sed id tristique lorem. Ut sodales turpis nec mauris gravida interdum. Cras pellentesque, purus at suscipit euismod, elit nunc cursus nisi, ut venenatis metus sapien id velit. Sed lectus orci, pharetra non pulvinar vel, ullamcorper id lorem. Donec vulputate tincidunt ipsum, ut lacinia tortor sollicitudin id. Nunc nec nibh ut felis venenatis egestas. Proin risus mauris, eleifend eget interdum in, venenatis sed velit. Praesent sodales elit ut odio viverra posuere. Donec sapien lorem, molestie in egestas eget, vulputate sed orci. Aenean elit sapien, pellentesque vitae tempor sit amet, sagittis et ligula. Mauris aliquam sapien sit amet lacus ultrices rutrum. Curabitur nec dolor sed elit varius dignissim a a lacus. Aliquam ac convallis enim.

Suspendisse orci massa, hendrerit sagittis lacinia consectetur, sagittis vitae purus. Aliquam id eros diam, eget elementum turpis. Nullam tellus magna, mollis in molestie id, venenatis rhoncus est. Proin id diam justo. Nunc tempus gravida justo at lobortis. Nam vitae venenatis nisi. Donec vel odio massa. Quisque interdum metus sit amet est iaculis tincidunt. Donec bibendum blandit purus, id semper orci aliquam quis. Nam tincidunt dolor eu felis ultricies tempor. Nulla non consectetur erat.

		DocStrap Copyright © 2012-2013 The contributors to the JSDoc3 and DocStrap projects.

		Documentation generated by JSDoc 3.3.0-alpha5
		on Sun Jun 1st 2014 using the DocStrap template.

redpajama_set_name: RedPajamaGithub


text:
namespace _02.Spy_Gram
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    // After arriving from the trip from the Splinter Trip problem, our hero Sam is feeling a
    // bit jet lagged, but he's ready to go to work!He needs to receive orders from his commanding
    // officers through the sophisticated messaging app, called SpyGram. The app uses a
    // sophisticated algorithm to encrypt messages.Since you're tired of jumbling text by hand for
    // 8 hours a day, you decide to write an algorithm to do it for you.
    // Sending messages works the following way – an outgoing message must follow the following format:
    // •	TO: {recipient}; MESSAGE: {message};
    // Here's what an example message looks like: "TO: GOSHO; MESSAGE: hi.;". If any message is not in
    // this format, you should ignore it.
    // Both parties are given a private key, which consists of digits of a variable length, with
    // which to encrypt/decrypt messages.The encryption algorithm is simple:
    // First, we take the message in the format above, then we shift right the first character of
    // our message by the value of the first character of our private key in the ASCII table, the
    // second character by the second private key character, and so on.If we run out of characters
    // in our private key(such as when our message is longer than our private key), then we start
    // over from the beginning of our private key.
    // So, with an example message of "hello", and an example private key of 123, it would look like this:
    // hello -> igomq
    // •	h gets shifted right by 1 character
    // •	e gets shifted right by 2 characters
    // •	l gets shifted right by 3 characters
    // •	l gets shifted right by 1 character (we ran out of characters in the private key and rolled over to the start)
    // •	o gets shifted right by 2 characters.
    // Input
    // The first line of our input consists of our private key.
    // Until we receive the command "END", we'll start receiving non-encrypted messages to send to
    // the command center.If we receive a message to send, we need to put it in our pending
    // messages collection.
    // After that, we need to sort the sent messages by sender name in ascending order.
    // Output
    // To send a message, all we have to do is encrypt it and print it on the console in the
    // standard outgoing message format.
    // Constraints
    // •	All valid recipient/sender names will be UPPERCASE and contain only Latin letters
    // •	Messages can contain ANY ASCII characterExamples
    // Input                                                  Output
    // 13234                                                  UR<#ESFJHV<#OHWTDIH>!vphel#cusvqf#mu>
    // TO: GRIM; MESSAGE: hello;                              UR<#KSLO>$NHUVEHH<#lfonr?
    // TO: ARCHER; MESSAGE: sneak around it;
    // END

    // Input                                                  Output
    // 142325555                                              US<#MJXYWFP=#OJXXFHI<#ckknwnevlxj@
    // TO: KOBIN; MESSAGE: one two three;                     US<#MTGNS<$OHUXFLJ;$qqg%y|t!xjugj@
    // TO: KESTREL; MESSAGE: affirmative;                     US<#VTRHQBRE\=%RJXTEIH<%qjy(w"jgy%yt!{qum@
    // T: REGAN; MESSAGE: help me;
    // TO: TOMCLANCY; MESSAGE: let's get to work;
    // TO: kestrel; MESSAGE: affirmative;
    // END

    // Input                                                  Output
    // 82738                                                  \QA#IZEOHZC"TH[[CNHB(cmiqzohwq~gB
    // TO: ARCHER; MESSAGE: affirmative;                      \QA#[IOB#UMUZDOM<'8=-"krvm=
    // FROM: SAM; MESSAGE: i'm pinned down;
    // TO: SAM; MESSAGE: 55% done;
    // FROM: SAM; MESSAGE: infiltrate the storage facility;
    // END
    public class Message
    {
        public string RecipientName { get; set; }
        public string EncryptedMessage { get; set; }
    }

    public class SpyGram
    {
        public static void Main()
        {
            var pattern = @"(^TO: )([A-Z]+)(; MESSAGE: )(.*?);$";
            var regex = new Regex(pattern);

            var encryptedMessages = new List<Message>();

            var privateKey = Console.ReadLine();
            var inputMessage = Console.ReadLine();

            while (inputMessage != "END")
            {
                if (!regex.IsMatch(inputMessage))
                {
                    goto Input;
                }

                EncryptedMessages(regex, encryptedMessages, privateKey, inputMessage);

                Input:;
                inputMessage = Console.ReadLine();
            }

            foreach (var message in encryptedMessages.OrderBy(x => x.RecipientName))
            {
                Console.WriteLine(message.EncryptedMessage);
            }
        }

        private static void EncryptedMessages(Regex regex, List<Message> encryptedMessages, string privateKey, string inputMessage)
        {
            var encryptedMessage = new StringBuilder();

            var index = 0; // This'll count the Private Key length.

            for (int i = 0; i < inputMessage.Length; i++)
            {
                var chr = inputMessage[i]; // This is the number of the character and the character itself in ASCII.

                if (index == privateKey.Length)
                {
                    index = 0; // This'll start count the Private Key length again from 0, when we ran out of the length.
                }

                var number = int.Parse(privateKey[index].ToString()); // This'll take the number behind the current Private Key's index.

                chr = (char)((int)chr + number); // Sum the number of the character behind ASCII with the number from the Private Key.

                encryptedMessage.Append(chr); // Add the new character.

                index++;
            }

            var recipient = regex.Match(inputMessage).Groups[2].Value;

            var message = new Message
            {
                RecipientName = recipient, // Keep the name of the recipient.
                EncryptedMessage = encryptedMessage.ToString() // Keep the encripted message.
            };

            encryptedMessages.Add(message); // Add all messages info in a list, so we could sort them by recipient's name for the output.
        }
    }
}


text:
/*
 * 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.
 */
package com.facebook.presto.spi;

import static java.util.Objects.requireNonNull;

public class BeginDeleteResult
{
    private final ConnectorTableHandle tableHandle;
    private final ColumnHandle rowIdHandle;

    public BeginDeleteResult(ConnectorTableHandle tableHandle, ColumnHandle rowIdHandle)
    {
        this.tableHandle = requireNonNull(tableHandle, "tableHandle is null");
        this.rowIdHandle = requireNonNull(rowIdHandle, "rowIdHandle is null");
    }

    public ConnectorTableHandle getTableHandle()
    {
        return tableHandle;
    }

    public ColumnHandle getRowIdHandle()
    {
        return rowIdHandle;
    }
}


text:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/lecture227');

// Post title, content
const postSchema = mongoose.Schema({
  title: 'String',
  content: 'String',
});

// User email, name
const userSchema = mongoose.Schema({
  email: {type: 'String', requred: true, unique: true},
  name: 'String',
  posts: [ postSchema ],
});

const User = mongoose.model('User', userSchema);

// var newUser = new User ({
//   email: 'Jane@brown.edu',
//   name: 'Jane Brown',
// });

// newUser.posts.push({
//   title: 'Oranges run wild',
//   content: `Oranges found at the bottom of a  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`
// });

// newUser.save(function(err, nUser) {
//   if (err) {
//     console.log(err);
//   } else {
//     console.log(`saved ${nUser}`);
//   }
// });

User.findOne({name: 'Jane Brown'}, function(err, fUser) {
  if (err) {
    console.log(err);
  } else {
    // console.log(fName);
    fUser.posts.push({
      title: 'Adding more stuff to mongo the hard way',
      content: 'How much more lorems do I needs, lots mores',
    });
    fUser.save(function(err, saved) {
      if (err) {
        console.log(err);
      } else {
        console.log(saved);
        console.log(fUser);
      }
    });
  }
});

// var newPost = new Post ({
//   title: 'Reflections on Apples',
//   content: 'They are lighter and smaller',
// });

// newPost.save(function(err, nPost) {
//   if (err) {
//     console.log(err);
//   } else {
//     console.log(`post saved`);
//   }
// });


text:
/** Extras **/

dt#type-calculated {
  display: none;
}

#module-type-FlatListComponent,
#module-type-ViewComponent,
#module-type-Impl,
#module-type-ImageComponent,
#module-type-ScrollViewComponent,
#module-CreateComponent,
#module-type-TextComponent,
#type-renderBag,
#type-dimensions,
#type-infoType,
#type-cursor,
#val-canUseCamera,
#type-result,
#type-subscription,
#type-duration,
#type-t,
#val-get,
#val-exitApp,
#val-addEventListener,
#val-removeEventListener,
#val-share,
#val-vibrate,
#val-cancel,
#type-type_,
#type-options,
#type-error,
#type-renderAccessory,
#type-viewToken,
#module-CreateComponent ~ article summary,
#module-CreateComponent ~ div summary {
  display: none;
}

#module-type-FlatListComponent,
#module-CreateComponent,
#module-CreateComponent ~ div > .include.spec details,
#module-CreateComponent ~ article > .include.spec details {
  overflow: hidden;
}

#module-CreateComponent ~ div dl,
#module-CreateComponent ~ article dl {
  display: flex;
  flex-direction: column-reverse;
}

.content > dl > dd {
  padding: 0;
  padding-top: 0.75em;
}


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Alyxia magnifolia F.M.Bailey

### Remarks
null


text:
use crate::{types::SqlType, ColumnDef, ColumnName, TableName};

#[derive(Debug, PartialEq, Clone)]
pub struct TableDef {
    pub name: TableName,

    /// comment of this table
    pub comment: Option<String>,

    /// columns of this table
    pub columns: Vec<ColumnDef>,

    /// views can also be generated
    pub is_view: bool,

    pub table_key: Vec<TableKey>,
}

impl TableDef {
    pub fn complete_name(&self) -> String {
        self.name.complete_name()
    }

    pub fn safe_name(&self) -> String {
        self.name.safe_name()
    }

    pub fn safe_complete_name(&self) -> String {
        self.name.safe_complete_name()
    }

    pub fn get_primary_column_names(&self) -> Vec<&ColumnName> {
        let mut primary: Vec<&ColumnName> = vec![];
        for key in &self.table_key {
            if let TableKey::PrimaryKey(ref pk) = key {
                for col in &pk.columns {
                    primary.push(col)
                }
            }
        }
        primary.sort_by(|a, b| a.name.cmp(&b.name));
        primary
    }

    pub fn get_non_primary_columns(&self) -> Vec<&ColumnDef> {
        let primary = self.get_primary_columns();
        self.columns
            .iter()
            .filter(|c| !primary.contains(c))
            .collect()
    }

    pub fn get_primary_columns(&self) -> Vec<&ColumnDef> {
        self.get_primary_column_names()
            .iter()
            .filter_map(|column_name| self.get_column(column_name))
            .collect()
    }

    pub fn is_primary_column(&self, column: &ColumnDef) -> bool {
        self.get_primary_columns().contains(&column)
    }

    pub fn get_primary_column_types(&self) -> Vec<&SqlType> {
        self.get_primary_columns()
            .iter()
            .map(|column| &column.specification.sql_type)
            .collect()
    }

    /// return the foreignkyes of this table
    pub fn get_foreign_keys(&self) -> Vec<&ForeignKey> {
        let mut foreign: Vec<&ForeignKey> = vec![];
        for key in &self.table_key {
            if let TableKey::ForeignKey(ref fk) = key {
                foreign.push(fk)
            }
        }
        foreign
    }

    /// return the table names which is foreign to this table
    pub fn get_foreign_tables(&self) -> Vec<&TableName> {
        self.get_foreign_keys()
            .iter()
            .map(|foreign| &foreign.foreign_table)
            .collect()
    }

    pub fn get_foreign_key_to_table(&self, table_name: &TableName) -> Option<&ForeignKey> {
        let foreign_keys: Vec<&ForeignKey> = self.get_foreign_keys();
        for fk in foreign_keys {
            if fk.foreign_table == *table_name {
                return Some(fk);
            }
        }
        None
    }

    /// get the (local_columns, foreign_columns) to the table
    pub fn get_local_foreign_columns_pair_to_table(
        &self,
        table_name: &TableName,
    ) -> Vec<(&ColumnName, &ColumnName)> {
        let foreign_keys: Vec<&ForeignKey> = self.get_foreign_keys();
        for fk in foreign_keys {
            if fk.foreign_table == *table_name {
                let mut container = vec![];
                for (local_column, referred_column) in
                    fk.columns.iter().zip(fk.referred_columns.iter())
                {
                    container.push((local_column, referred_column));
                }
                return container;
            }
        }
        vec![]
    }

    fn get_foreign_columns_to_table(&self, table_name: &TableName) -> Vec<&ColumnDef> {
        self.get_foreign_column_names_to_table(table_name)
            .iter()
            .filter_map(|column_name| self.get_column(column_name))
            .collect()
    }

    pub fn get_foreign_column_types_to_table(&self, table_name: &TableName) -> Vec<&SqlType> {
        self.get_foreign_columns_to_table(table_name)
            .iter()
            .map(|column| &column.specification.sql_type)
            .collect()
    }

    pub fn get_foreign_column_names_to_table(&self, table_name: &TableName) -> Vec<&ColumnName> {
        let mut foreign_columns = vec![];
        let foreign_keys = self.get_foreign_key_to_table(table_name);
        for fk in &foreign_keys {
            for fk_column in &fk.columns {
                foreign_columns.push(fk_column);
            }
        }
        foreign_columns
    }

    /// get the column names of this table
    pub fn get_foreign_column_names(&self) -> Vec<&ColumnName> {
        let mut foreign_columns = vec![];
        let foreign_keys = self.get_foreign_keys();
        for fk in &foreign_keys {
            for fk_column in &fk.columns {
                foreign_columns.push(fk_column);
            }
        }
        foreign_columns
    }

    /// return the local columns of this table
    /// that is referred by the argument table name
    pub fn get_referred_columns_to_table(
        &self,
        table_name: &TableName,
    ) -> Option<&Vec<ColumnName>> {
        let foreign_keys: Vec<&ForeignKey> = self.get_foreign_keys();
        for fk in foreign_keys {
            if fk.foreign_table == *table_name {
                return Some(&fk.referred_columns);
            }
        }
        None
    }

    /// find the column which matches this `column_name`
    pub fn get_column(&self, column_name: &ColumnName) -> Option<&ColumnDef> {
        self.columns.iter().find(|c| c.name == *column_name)
    }
}

/// example:
///     category { id, name }
///     product { product_id, name, category_id }
///
/// if the table in context is product and the foreign table is category
/// ForeignKey{
///     name: product_category_fkey
///     columns: _category_id_
///     foreign_table: category
///     referred_columns: _id_
/// }
#[derive(Debug, PartialEq, Clone)]
pub struct ForeignKey {
    pub name: Option<String>,
    // the local columns of this table local column = foreign_column
    pub columns: Vec<ColumnName>,
    // referred foreign table
    pub foreign_table: TableName,
    // referred column of the foreign table
    // this is most likely the primary key of the table in context
    pub referred_columns: Vec<ColumnName>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct Key {
    pub name: Option<String>,
    pub columns: Vec<ColumnName>,
}

#[derive(Debug, PartialEq, Clone)]
pub enum TableKey {
    PrimaryKey(Key),
    UniqueKey(Key),
    Key(Key),
    ForeignKey(ForeignKey),
}

#[derive(Debug)]
pub struct SchemaContent {
    pub schema: String,
    pub tablenames: Vec<TableName>,
    pub views: Vec<TableName>,
}

#[cfg(test)]
#[cfg(feature = "with-postgres")]
mod test {
    use crate::{table::*, *};
    use log::*;

    #[test]
    fn film_table_info() {
        let db_url = "postgres://postgres:p0stgr3s@localhost:5432/sakila";
        let mut pool = Pool::new();
        let mut em = pool.em(db_url).expect("must be ok");
        let table = em
            .get_table(&TableName::from("public.film"))
            .expect("must have a table");
        println!("table: {:#?}", table);
    }

    #[test]
    fn test_foreign_tables() {
        let db_url = "postgres://postgres:p0stgr3s@localhost:5432/sakila";
        let mut pool = Pool::new();
        let mut em = pool.em(db_url).expect("must be ok");
        let table = em
            .get_table(&TableName::from("public.film_actor"))
            .expect("must be ok")
            .expect("must have a table");

        println!("table: {:#?}", table);
        let foreign_tables = table.get_foreign_tables();
        println!("foreign_tables: {:#?}", foreign_tables);
        assert_eq!(
            foreign_tables,
            vec![
                &TableName::from("public.actor"),
                &TableName::from("public.film"),
            ]
        );
    }

    #[test]
    fn referred_columns() {
        let db_url = "postgres://postgres:p0stgr3s@localhost:5432/sakila";
        let mut pool = Pool::new();
        let em = pool.em(db_url);
        let mut db = pool.db(db_url).unwrap();
        assert!(em.is_ok());
        let film_tablename = TableName::from("public.film");
        let film = db
            .get_table(&film_tablename)
            .expect("must be ok")
            .expect("must have a table");
        let film_actor_tablename = TableName::from("public.film_actor");
        let film_actor = db
            .get_table(&film_actor_tablename)
            .expect("must be ok")
            .expect("must have a table");
        let rc = film_actor.get_referred_columns_to_table(&film.name);
        info!("rc: {:#?}", rc);
        assert_eq!(
            rc,
            Some(&vec![ColumnName {
                name: "film_id".to_string(),
                table: None,
                alias: None,
            }])
        );
    }

    #[test]
    fn referred_columns_hero_id() {
        let db_url = "postgres://postgres:p0stgr3s@localhost:5432/dota";
        let mut pool = Pool::new();
        let mut em = pool.em(db_url).expect("must be ok");
        let hero_tablename = TableName::from("public.hero");
        let hero = em
            .get_table(&hero_tablename)
            .expect("must be ok")
            .expect("must have a table");

        let hero_ability_tablename = TableName::from("public.hero_ability");
        let hero_ability = em
            .get_table(&hero_ability_tablename)
            .expect("must be ok")
            .expect("must have a table");

        info!("hero {:#?}", hero);
        info!("hero ability {:#?}", hero_ability);
        let rc = hero_ability.get_referred_columns_to_table(&hero.name);
        info!("rc: {:#?}", rc);
        assert_eq!(
            rc,
            Some(&vec![ColumnName {
                name: "id".to_string(),
                table: None,
                alias: None,
            }])
        );
        let foreign_key = hero_ability.get_foreign_key_to_table(&hero.name);
        info!("foreign_key: {:#?}", foreign_key);
        assert_eq!(
            foreign_key,
            Some(&ForeignKey {
                name: Some("hero_id_fkey".to_string()),
                columns: vec![ColumnName {
                    name: "hero_id".to_string(),
                    table: None,
                    alias: None,
                }],
                foreign_table: TableName {
                    name: "hero".to_string(),
                    schema: Some("public".to_string()),
                    alias: None,
                },
                referred_columns: vec![ColumnName {
                    name: "id".to_string(),
                    table: None,
                    alias: None,
                }],
            })
        );
    }
}


text:
import $ from "jquery";

import { Suggestions } from "./suggestions";

var methods = {
    enrichSuggestion: function(suggestion, selectionOptions) {
        var that = this,
            resolver = $.Deferred();

        if (
            !that.options.enrichmentEnabled ||
            !that.type.enrichmentEnabled ||
            !that.requestMode.enrichmentEnabled ||
            (selectionOptions && selectionOptions.dontEnrich)
        ) {
            return resolver.resolve(suggestion);
        }

        // if current suggestion is already enriched, use it
        if (suggestion.data && suggestion.data.qc != null) {
            return resolver.resolve(suggestion);
        }

        that.disableDropdown();

        var query = that.type.getEnrichmentQuery(suggestion);
        var customParams = that.type.enrichmentParams;
        var requestOptions = {
            noCallbacks: true,
            useEnrichmentCache: true,
            method: that.type.enrichmentMethod
        };

        // Set `currentValue` to make `processResponse` to consider enrichment response valid
        that.currentValue = query;

        // prevent request abortion during onBlur
        that.enrichPhase = that
            .getSuggestions(query, customParams, requestOptions)
            .always(function() {
                that.enableDropdown();
            })
            .done(function(suggestions) {
                var enrichedSuggestion = suggestions && suggestions[0];

                resolver.resolve(
                    enrichedSuggestion || suggestion,
                    !!enrichedSuggestion
                );
            })
            .fail(function() {
                resolver.resolve(suggestion);
            });

        return resolver;
    },

    /**
     * Injects enriched suggestion into response
     * @param response
     * @param query
     */
    enrichResponse: function(response, query) {
        var that = this,
            enrichedSuggestion = that.enrichmentCache[query];

        if (enrichedSuggestion) {
            $.each(response.suggestions, function(i, suggestion) {
                if (suggestion.value === query) {
                    response.suggestions[i] = enrichedSuggestion;
                    return false;
                }
            });
        }
    }
};

$.extend(Suggestions.prototype, methods);


text:
<?php

require_once(dirname(__FILE__)."/../pfccommand.class.php");

class pfcCommand_asknick extends pfcCommand
{
  function run(&$xml_reponse, $p)
  {
    $clientid    = $p["clientid"];
    $param       = $p["param"];
    $sender      = $p["sender"];
    $recipient   = $p["recipient"];
    $recipientid = $p["recipientid"];

    $c =& pfcGlobalConfig::Instance();
    $u =& pfcUserConfig::Instance();

    $nicktochange = phpFreeChat::FilterNickname($param);

    if ($c->frozen_nick)
    {
      // assign a random nick
      $cmdp = $p;
      $cmdp["param"] = $nicktochange."".rand(1,1000);
      $cmd =& pfcCommand::Factory("nick");
      $cmd->run($xml_reponse, $cmdp);
    }
    else
    {
      if ($nicktochange == "")
      {
        $nicktochange = $u->nick;
        $msg = _pfc("Please enter your nickname");
      }
      else
        $msg = "'".$nicktochange."' is used, please choose another nickname.";
      $xml_reponse->script("var newnick = prompt('".addslashes($msg)."', '".addslashes($nicktochange)."'); if (newnick) pfc.sendRequest('/nick \"'+newnick+'\"');");
    }
  }
}

?>


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.effine</groupId>
	<artifactId>code-generator</artifactId>
	<version>1.0</version>
	<packaging>war</packaging>

	<name>code-generator</name>
	<url>https://github.com/effine/code-generator</url>

	<properties>
		<!-- 文件拷贝时的编码 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<!-- 编译时的编码 -->
		<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.13</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7-beta1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-velocity</artifactId>
			<version>1.1.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>code-generator</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>utf-8</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<encoding>utf-8</encoding>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


text:
class FilePath;
class PluginInstallerObserver;
class WeakPluginInstallerObserver;

namespace net {
class URLRequestContextGetter;
}

class PluginInstaller {
 public:
  enum State {
    kStateIdle,
    kStateDownloading,
  };

  PluginInstaller(const std::string& identifier,
                  const GURL& plugin_url,
                  const GURL& help_url,
                  const string16& name,
                  bool url_for_display);
  ~PluginInstaller();

  void AddObserver(PluginInstallerObserver* observer);
  void RemoveObserver(PluginInstallerObserver* observer);

  void AddWeakObserver(WeakPluginInstallerObserver* observer);
  void RemoveWeakObserver(WeakPluginInstallerObserver* observer);

  State state() const { return state_; }

  // Unique identifier for the plug-in. Should be kept in sync with the
  // identifier in plugin_list.cc.
  const std::string& identifier() const { return identifier_; }

  // Human-readable name of the plug-in.
  const string16& name() const { return name_; }

  // If |url_for_display| is false, |plugin_url| is the URL of the download page
  // for the plug-in, which should be opened in a new tab. If it is true,
  // |plugin_url| is the URL of the plug-in installer binary, which can be
  // directly downloaded.
  bool url_for_display() const { return url_for_display_; }
  const GURL& plugin_url() const { return plugin_url_; }

  // URL to open when the user clicks on the "Problems installing?" link.
  const GURL& help_url() const { return help_url_; }

  void StartInstalling(net::URLRequestContextGetter* request_context);

  // Called when the browser opened the download URL in a new tab, to notify
  // observers.
  void DidOpenDownloadURL();

 private:
  void DidFinishDownload(const FilePath& downloaded_file);
  void DownloadError(const std::string& msg);

  State state_;
  ObserverList<PluginInstallerObserver> observers_;
  ObserverList<WeakPluginInstallerObserver> weak_observers_;

  std::string identifier_;
  GURL plugin_url_;
  GURL help_url_;
  string16 name_;
  bool url_for_display_;

  DISALLOW_COPY_AND_ASSIGN(PluginInstaller);
};

#endif  // CHROME_BROWSER_PLUGIN_INSTALLER_H_


text:
#region Usings

using System;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web.Optimization;
using Ironman.Core.Assets.Interfaces;
using Utilities.IoC.Interfaces;

#endregion Usings

namespace Ironman.Core.Assets.Transformers
{
    /// <summary>
    /// Transformer class used
    /// </summary>
    public class Transformer : IBundleTransform
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="Manager">The manager.</param>
        public Transformer(AssetManager Manager)
        {
            Contract.Requires<ArgumentNullException>(Manager != null, "Manager");
            this.Manager = Manager;
        }

        /// <summary>
        /// Manager that loads basic asset stuff
        /// </summary>
        /// <value>The manager.</value>
        protected AssetManager Manager { get; private set; }

        /// <summary>
        /// Processes the bundle
        /// </summary>
        /// <param name="context">Bundle context</param>
        /// <param name="response">Bundle response</param>
        public void Process(BundleContext context, BundleResponse response)
        {
            if (context == null || response == null)
                return;
            if (!context.EnableInstrumentation)
            {
                Manager.Process(response.Files.Select(x => new Asset(x.IncludedVirtualPath, Manager)).ToList<IAsset>(), response);
            }
        }
    }
}


text:
import unittest

# third party
from mock import MagicMock, patch

# the ape
from theape.infrastructure.arguments.listarguments import List, ListStrategy
from theape.infrastructure.arguments.basestrategy import BaseStrategy

class TestList(unittest.TestCase):
    def setUp(self):
        self.args = ['list']
        self.arguments = List(args=self.args)
        return

    def test_constructor(self):
        """
        Does it build correctly?
        """
        arguments = List(args=['list'])

        # inderited default
        self.assertFalse(arguments.pudb)
        return

    def test_modules(self):
        """
        Does it get the list of plugin modules?
        """
        # default to empty list
        self.assertEqual([], self.arguments.modules)

        # positional arguments
        modules = 'ape bat chameleon'.split()
        self.arguments.reset()
        self.arguments.args = self.args + modules
        self.assertEqual(modules, self.arguments.modules)
        return

class TestListStrategy(unittest.TestCase):
    def setUp(self):
        self.quartermaster = MagicMock()
        ListStrategy.quartermaster = self.quartermaster
        self.strategy = ListStrategy()
        return

    def test_constructor(self):
        """
        Does it build?
        """
        strategy = ListStrategy()

        self.assertIsInstance(strategy, BaseStrategy)

        # the mock insertion in SetUp breaks this
        #self.assertIs(strategy.quartermaster, BaseStrategy.quartermaster)
        return

    def test_function(self):
        """
        Does it list the plugins?
        """
        args = MagicMock()

        args.modules = 'a b c'.split()
        self.strategy.function(args)
        self.assertEqual(args.modules, self.quartermaster.external_modules)
        self.quartermaster.list_plugins.assert_called_with()
        return

    def test_try_except(self):
        """
        Does the decorator catch exceptions?
        """
        self.quartermaster.list_plugins.side_effect = Exception("Something Bad")
        self.strategy.function()
        return


text:
@class TyphoonComponentFactory;
@protocol TyphoonInjection;

@interface TyphoonOptionMatcher (Internal)

- (instancetype)initWithBlock:(TyphoonMatcherBlock)block;

- (id<TyphoonInjection>)injectionMatchedValue:(id)value;

@end


text:
<?php namespace Thujohn\Twitter\Traits;

use Exception;

Trait FavoriteTrait {

	/**
	 * Returns the 20 most recent Tweets favorited by the authenticating or specified user.
	 *
	 * Parameters :
	 * - user_id
	 * - screen_name
	 * - count (1-200)
	 * - since_id
	 * - max_id
	 * - include_entities (0|1)
	 */
	public function getFavorites($parameters = [])
	{
		return $this->get('favorites/list', $parameters);
	}

	/**
	 * Un-favorites the status specified in the ID parameter as the authenticating user. Returns the un-favorited status in the requested format when successful.
	 *
	 * Parameters :
	 * - id
	 * - include_entities (0|1)
	 */
	public function destroyFavorite($parameters = [])
	{
		if (!array_key_exists('id', $parameters))
		{
			throw new Exception('Parameter required missing : id');
		}

		return $this->post('favorites/destroy', $parameters);
	}

	/**
	 * Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful.
	 *
	 * Parameters :
	 * - id
	 * - include_entities (0|1)
	 */
	public function postFavorite($parameters = [])
	{
		if (!array_key_exists('id', $parameters))
		{
			throw new Exception('Parameter required missing : id');
		}

		return $this->post('favorites/create', $parameters);
	}

}


text:
from setuptools import setup

setup(
    name='jingo',
    version='0.6.1',
    description='An adapter for using Jinja2 templates with Django.',
    long_description=open('README.rst').read(),
    author='Jeff Balogh',
    author_email='jbalogh@mozilla.com',
    url='http://github.com/jbalogh/jingo',
    license='BSD',
    packages=['jingo'],
    include_package_data=True,
    zip_safe=False,
    install_requires=['jinja2'],
    classifiers=[
        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        # I don't know what exactly this means, but why not?
        'Environment :: Web Environment :: Mozilla',
        'Framework :: Django',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ]
)


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<TITLE>
XmlSchemaType (Java Platform SE 6)
</TITLE>

<META NAME="date" CONTENT="2007-03-19">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">

      概述
      软件包
    类
      使用
      树
      已过时
      索引
      帮助

JavaTM Platform
Standard Ed. 6

 上一个类
 下一个类

  框架
 无框架

  所有类

  摘要: 必需 | 可选

详细信息: 元素

javax.xml.bind.annotation

注释类型 XmlSchemaType

@Retention(value=RUNTIME)
@Target(value={FIELD,METHOD,PACKAGE})
public @interface XmlSchemaType

将 Java 类型映射到一个简单的模式内置类型。

 用法

<tt>@XmlSchemaType</tt> 注释可以与以下程序元素一起使用:

 JavaBean 属性

 字段

 包

 为 Java 类型定义的 <tt>@XmlSchemaType</tt> 注释可应用于所有对属性/字段中的 Java 类型的引用。在属性/字段中指定的 <tt>@XmlSchemaType</tt> 注释重写在包级别上指定的 <tt>@XmlSchemaType</tt> 注释。

此注释可与以下注释一起使用:
 XmlElement、XmlAttribute。

示例 1:自定义字段上的 XMLGregorianCalendar 的映射。

     //Example: Code fragment
     public class USPrice {
         @XmlElement
         @XmlSchemaType(name="date")
         public XMLGregorianCalendar date;
     }

     <!-- Example: Local XML Schema element -->
     <xs:complexType name="USPrice"/>
       <xs:sequence>
         <xs:element name="date" type="xs:date"/>
       </sequence>
     </xs:complexType>

 示例 2:自定义包级别的 XMLGregorianCalendar 的映射。

     package foo;
     @javax.xml.bind.annotation.XmlSchemaType(
          name="date", type=javax.xml.datatype.XMLGregorianCalendar.class)
     }

从以下版本开始:

JAXB2.0

必需元素摘要

 String
name

可选元素摘要

 String
namespace

 Class
type

          如果此注释用于包级别上,那么必须指定 type() 的值。

元素详细信息

name

public abstract String name

namespace

public abstract String namespace

默认值:
"http://www.w3.org/2001/XMLSchema"

type

public abstract Class type

如果此注释用于包级别上,那么必须指定 type() 的值。

默认值:
javax.xml.bind.annotation.XmlSchemaType.DEFAULT.class

      概述
      软件包
    类
      使用
      树
      已过时
      索引
      帮助

JavaTM Platform
Standard Ed. 6

 上一个类
 下一个类

  框架
 无框架

  所有类

  摘要: 必需 | 可选

详细信息: 元素

提交错误或意见
有关更多的 API 参考资料和开发人员文档,请参阅 Java SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。
版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策。


text:
<?php

namespace Doctrine\ORM\Mapping\Driver;

use Doctrine\Common\Persistence\Mapping\ClassMetadata,
    Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
    Doctrine\ORM\Mapping\MappingException,
    Symfony\Component\Yaml\Yaml;

/**
 * The YamlDriver reads the mapping metadata from yaml schema files.
 *
 * @since 2.0
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author Jonathan H. Wage <jonwage@gmail.com>
 * @author Roman Borschel <roman@code-factory.org>
 */
class YamlDriver extends FileDriver
{
    const DEFAULT_FILE_EXTENSION = '.dcm.yml';

    /**
     * {@inheritDoc}
     */
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
    {
        parent::__construct($locator, $fileExtension);
    }

    /**
     * {@inheritDoc}
     */
    public function loadMetadataForClass($className, ClassMetadata $metadata)
    {
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
        $element = $this->getElement($className);

        if ($element['type'] == 'entity') {
            if (isset($element['repositoryClass'])) {
                $metadata->setCustomRepositoryClass($element['repositoryClass']);
            }
            if (isset($element['readOnly']) && $element['readOnly'] == true) {
                $metadata->markReadOnly();
            }
        } else if ($element['type'] == 'mappedSuperclass') {
            $metadata->setCustomRepositoryClass(
                isset($element['repositoryClass']) ? $element['repositoryClass'] : null
            );
            $metadata->isMappedSuperclass = true;
        } else {
            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
        }

        // Evaluate root level properties
        $table = array();
        if (isset($element['table'])) {
            $table['name'] = $element['table'];
        }
        $metadata->setPrimaryTable($table);

        // Evaluate named queries
        if (isset($element['namedQueries'])) {
            foreach ($element['namedQueries'] as $name => $queryMapping) {
                if (is_string($queryMapping)) {
                    $queryMapping = array('query' => $queryMapping);
                }

                if ( ! isset($queryMapping['name'])) {
                    $queryMapping['name'] = $name;
                }

                $metadata->addNamedQuery($queryMapping);
            }
        }

        // Evaluate named native queries
        if (isset($element['namedNativeQueries'])) {
            foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
                if (!isset($mappingElement['name'])) {
                    $mappingElement['name'] = $name;
                }
                $metadata->addNamedNativeQuery(array(
                    'name'              => $mappingElement['name'],
                    'query'             => isset($mappingElement['query']) ? $mappingElement['query'] : null,
                    'resultClass'       => isset($mappingElement['resultClass']) ? $mappingElement['resultClass'] : null,
                    'resultSetMapping'  => isset($mappingElement['resultSetMapping']) ? $mappingElement['resultSetMapping'] : null,
                ));
            }
        }

        // Evaluate sql result set mappings
        if (isset($element['sqlResultSetMappings'])) {
            foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
                if (!isset($resultSetMapping['name'])) {
                    $resultSetMapping['name'] = $name;
                }

                $entities = array();
                $columns  = array();
                if (isset($resultSetMapping['entityResult'])) {
                    foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
                        $entityResult = array(
                            'fields'                => array(),
                            'entityClass'           => isset($entityResultElement['entityClass']) ? $entityResultElement['entityClass'] : null,
                            'discriminatorColumn'   => isset($entityResultElement['discriminatorColumn']) ? $entityResultElement['discriminatorColumn'] : null,
                        );

                        if (isset($entityResultElement['fieldResult'])) {
                            foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
                                $entityResult['fields'][] = array(
                                    'name'      => isset($fieldResultElement['name']) ? $fieldResultElement['name'] : null,
                                    'column'    => isset($fieldResultElement['column']) ? $fieldResultElement['column'] : null,
                                );
                            }
                        }

                        $entities[] = $entityResult;
                    }
                }

                if (isset($resultSetMapping['columnResult'])) {
                    foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
                        $columns[] = array(
                            'name' => isset($columnResultAnnot['name']) ? $columnResultAnnot['name'] : null,
                        );
                    }
                }

                $metadata->addSqlResultSetMapping(array(
                    'name'          => $resultSetMapping['name'],
                    'entities'      => $entities,
                    'columns'       => $columns
                ));
            }
        }

        /* not implemented specially anyway. use table = schema.table
        if (isset($element['schema'])) {
            $metadata->table['schema'] = $element['schema'];
        }*/

        if (isset($element['inheritanceType'])) {
            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));

            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
                // Evaluate discriminatorColumn
                if (isset($element['discriminatorColumn'])) {
                    $discrColumn = $element['discriminatorColumn'];
                    $metadata->setDiscriminatorColumn(array(
                        'name' => isset($discrColumn['name']) ? (string)$discrColumn['name'] : null,
                        'type' => isset($discrColumn['type']) ? (string)$discrColumn['type'] : null,
                        'length' => isset($discrColumn['length']) ? (string)$discrColumn['length'] : null,
                        'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string)$discrColumn['columnDefinition'] : null
                    ));
                } else {
                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
                }

                // Evaluate discriminatorMap
                if (isset($element['discriminatorMap'])) {
                    $metadata->setDiscriminatorMap($element['discriminatorMap']);
                }
            }
        }

        // Evaluate changeTrackingPolicy
        if (isset($element['changeTrackingPolicy'])) {
            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
                    . strtoupper($element['changeTrackingPolicy'])));
        }

        // Evaluate indexes
        if (isset($element['indexes'])) {
            foreach ($element['indexes'] as $name => $index) {
                if ( ! isset($index['name'])) {
                    $index['name'] = $name;
                }

                if (is_string($index['columns'])) {
                    $columns = explode(',', $index['columns']);
                } else {
                    $columns = $index['columns'];
                }

                $metadata->table['indexes'][$index['name']] = array(
                    'columns' => $columns
                );
            }
        }

        // Evaluate uniqueConstraints
        if (isset($element['uniqueConstraints'])) {
            foreach ($element['uniqueConstraints'] as $name => $unique) {
                if ( ! isset($unique['name'])) {
                    $unique['name'] = $name;
                }

                if (is_string($unique['columns'])) {
                    $columns = explode(',', $unique['columns']);
                } else {
                    $columns = $unique['columns'];
                }

                $metadata->table['uniqueConstraints'][$unique['name']] = array(
                    'columns' => $columns
                );
            }
        }

        if (isset($element['options'])) {
            $metadata->table['options'] = $element['options'];
        }

        $associationIds = array();
        if (isset($element['id'])) {
            // Evaluate identifier settings
            foreach ($element['id'] as $name => $idElement) {
                if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
                    $associationIds[$name] = true;
                    continue;
                }

                $mapping = array(
                    'id' => true,
                    'fieldName' => $name
                );

                if (isset($idElement['type'])) {
                    $mapping['type'] = $idElement['type'];
                }

                if (isset($idElement['column'])) {
                    $mapping['columnName'] = $idElement['column'];
                }

                if (isset($idElement['length'])) {
                    $mapping['length'] = $idElement['length'];
                }

                if (isset($idElement['columnDefinition'])) {
                    $mapping['columnDefinition'] = $idElement['columnDefinition'];
                }

                $metadata->mapField($mapping);

                if (isset($idElement['generator'])) {
                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
                            . strtoupper($idElement['generator']['strategy'])));
                }
                // Check for SequenceGenerator/TableGenerator definition
                if (isset($idElement['sequenceGenerator'])) {
                    $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
                } else if (isset($idElement['customIdGenerator'])) {
                    $customGenerator = $idElement['customIdGenerator'];
                    $metadata->setCustomGeneratorDefinition(array(
                        'class' => (string) $customGenerator['class']
                    ));
                } else if (isset($idElement['tableGenerator'])) {
                    throw MappingException::tableIdGeneratorNotImplemented($className);
                }
            }
        }

        // Evaluate fields
        if (isset($element['fields'])) {
            foreach ($element['fields'] as $name => $fieldMapping) {

                $mapping = $this->columnToArray($name, $fieldMapping);

                if (isset($fieldMapping['id'])) {
                    $mapping['id'] = true;
                    if (isset($fieldMapping['generator']['strategy'])) {
                        $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
                                . strtoupper($fieldMapping['generator']['strategy'])));
                    }
                }

                $metadata->mapField($mapping);
            }
        }

        // Evaluate oneToOne relationships
        if (isset($element['oneToOne'])) {
            foreach ($element['oneToOne'] as $name => $oneToOneElement) {
                $mapping = array(
                    'fieldName' => $name,
                    'targetEntity' => $oneToOneElement['targetEntity']
                );

                if (isset($associationIds[$mapping['fieldName']])) {
                    $mapping['id'] = true;
                }

                if (isset($oneToOneElement['fetch'])) {
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
                }

                if (isset($oneToOneElement['mappedBy'])) {
                    $mapping['mappedBy'] = $oneToOneElement['mappedBy'];
                } else {
                    if (isset($oneToOneElement['inversedBy'])) {
                        $mapping['inversedBy'] = $oneToOneElement['inversedBy'];
                    }

                    $joinColumns = array();

                    if (isset($oneToOneElement['joinColumn'])) {
                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
                    } else if (isset($oneToOneElement['joinColumns'])) {
                        foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
                            if ( ! isset($joinColumnElement['name'])) {
                                $joinColumnElement['name'] = $joinColumnName;
                            }

                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
                        }
                    }

                    $mapping['joinColumns'] = $joinColumns;
                }

                if (isset($oneToOneElement['cascade'])) {
                    $mapping['cascade'] = $oneToOneElement['cascade'];
                }

                if (isset($oneToOneElement['orphanRemoval'])) {
                    $mapping['orphanRemoval'] = (bool)$oneToOneElement['orphanRemoval'];
                }

                $metadata->mapOneToOne($mapping);
            }
        }

        // Evaluate oneToMany relationships
        if (isset($element['oneToMany'])) {
            foreach ($element['oneToMany'] as $name => $oneToManyElement) {
                $mapping = array(
                    'fieldName' => $name,
                    'targetEntity' => $oneToManyElement['targetEntity'],
                    'mappedBy' => $oneToManyElement['mappedBy']
                );

                if (isset($oneToManyElement['fetch'])) {
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']);
                }

                if (isset($oneToManyElement['cascade'])) {
                    $mapping['cascade'] = $oneToManyElement['cascade'];
                }

                if (isset($oneToManyElement['orphanRemoval'])) {
                    $mapping['orphanRemoval'] = (bool)$oneToManyElement['orphanRemoval'];
                }

                if (isset($oneToManyElement['orderBy'])) {
                    $mapping['orderBy'] = $oneToManyElement['orderBy'];
                }

                if (isset($oneToManyElement['indexBy'])) {
                    $mapping['indexBy'] = $oneToManyElement['indexBy'];
                }

                $metadata->mapOneToMany($mapping);
            }
        }

        // Evaluate manyToOne relationships
        if (isset($element['manyToOne'])) {
            foreach ($element['manyToOne'] as $name => $manyToOneElement) {
                $mapping = array(
                    'fieldName' => $name,
                    'targetEntity' => $manyToOneElement['targetEntity']
                );

                if (isset($associationIds[$mapping['fieldName']])) {
                    $mapping['id'] = true;
                }

                if (isset($manyToOneElement['fetch'])) {
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
                }

                if (isset($manyToOneElement['inversedBy'])) {
                    $mapping['inversedBy'] = $manyToOneElement['inversedBy'];
                }

                $joinColumns = array();

                if (isset($manyToOneElement['joinColumn'])) {
                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
                } else if (isset($manyToOneElement['joinColumns'])) {
                    foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $joinColumnName;
                        }

                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
                    }
                }

                $mapping['joinColumns'] = $joinColumns;

                if (isset($manyToOneElement['cascade'])) {
                    $mapping['cascade'] = $manyToOneElement['cascade'];
                }

                $metadata->mapManyToOne($mapping);
            }
        }

        // Evaluate manyToMany relationships
        if (isset($element['manyToMany'])) {
            foreach ($element['manyToMany'] as $name => $manyToManyElement) {
                $mapping = array(
                    'fieldName' => $name,
                    'targetEntity' => $manyToManyElement['targetEntity']
                );

                if (isset($manyToManyElement['fetch'])) {
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']);
                }

                if (isset($manyToManyElement['mappedBy'])) {
                    $mapping['mappedBy'] = $manyToManyElement['mappedBy'];
                } else if (isset($manyToManyElement['joinTable'])) {

                    $joinTableElement = $manyToManyElement['joinTable'];
                    $joinTable = array(
                        'name' => $joinTableElement['name']
                    );

                    if (isset($joinTableElement['schema'])) {
                        $joinTable['schema'] = $joinTableElement['schema'];
                    }

                    foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $joinColumnName;
                        }

                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
                    }

                    foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $joinColumnName;
                        }

                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
                    }

                    $mapping['joinTable'] = $joinTable;
                }

                if (isset($manyToManyElement['inversedBy'])) {
                    $mapping['inversedBy'] = $manyToManyElement['inversedBy'];
                }

                if (isset($manyToManyElement['cascade'])) {
                    $mapping['cascade'] = $manyToManyElement['cascade'];
                }

                if (isset($manyToManyElement['orderBy'])) {
                    $mapping['orderBy'] = $manyToManyElement['orderBy'];
                }

                if (isset($manyToManyElement['indexBy'])) {
                    $mapping['indexBy'] = $manyToManyElement['indexBy'];
                }

                if (isset($manyToManyElement['orphanRemoval'])) {
                    $mapping['orphanRemoval'] = (bool)$manyToManyElement['orphanRemoval'];
                }

                $metadata->mapManyToMany($mapping);
            }
        }

        // Evaluate associationOverride
        if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {

            foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
                $override   = array();

                // Check for joinColumn
                if (isset($associationOverrideElement['joinColumn'])) {
                    $joinColumns = array();
                    foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $name;
                        }
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
                    }
                    $override['joinColumns'] = $joinColumns;
                }

                // Check for joinTable
                if (isset($associationOverrideElement['joinTable'])) {

                    $joinTableElement   = $associationOverrideElement['joinTable'];
                    $joinTable          =  array(
                        'name' => $joinTableElement['name']
                    );

                    if (isset($joinTableElement['schema'])) {
                        $joinTable['schema'] = $joinTableElement['schema'];
                    }

                    foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $name;
                        }

                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
                    }

                    foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
                        if ( ! isset($joinColumnElement['name'])) {
                            $joinColumnElement['name'] = $name;
                        }

                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
                    }

                    $override['joinTable'] = $joinTable;
                }

                $metadata->setAssociationOverride($fieldName, $override);
            }
        }

        // Evaluate associationOverride
        if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {

            foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
                $mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
                $metadata->setAttributeOverride($fieldName, $mapping);
            }
        }

        // Evaluate lifeCycleCallbacks
        if (isset($element['lifecycleCallbacks'])) {
            foreach ($element['lifecycleCallbacks'] as $type => $methods) {
                foreach ($methods as $method) {
                    $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type));
                }
            }
        }
    }

    /**
     * Constructs a joinColumn mapping array based on the information
     * found in the given join column element.
     *
     * @param array $joinColumnElement The array join column element
     * @return array The mapping array.
     */
    private function joinColumnToArray($joinColumnElement)
    {
        $joinColumn = array();
        if (isset($joinColumnElement['referencedColumnName'])) {
            $joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
        }

        if (isset($joinColumnElement['name'])) {
            $joinColumn['name'] = (string) $joinColumnElement['name'];
        }

        if (isset($joinColumnElement['fieldName'])) {
            $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
        }

        if (isset($joinColumnElement['unique'])) {
            $joinColumn['unique'] = (bool) $joinColumnElement['unique'];
        }

        if (isset($joinColumnElement['nullable'])) {
            $joinColumn['nullable'] = (bool) $joinColumnElement['nullable'];
        }

        if (isset($joinColumnElement['onDelete'])) {
            $joinColumn['onDelete'] = $joinColumnElement['onDelete'];
        }

        if (isset($joinColumnElement['columnDefinition'])) {
            $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
        }

        return $joinColumn;
    }

    /**
     * Parse the given column as array
     *
     * @param   string  $fieldName
     * @param   array   $column
     * @return  array
     */
    private function columnToArray($fieldName, $column)
    {
        $mapping = array(
            'fieldName' => $fieldName
        );

        if (isset($column['type'])) {
            $params = explode('(', $column['type']);
            $column['type']  = $params[0];
            $mapping['type'] = $column['type'];

            if (isset($params[1])) {
                $column['length'] = substr($params[1], 0, strlen($params[1]) - 1);
            }
        }

        if (isset($column['column'])) {
            $mapping['columnName'] = $column['column'];
        }

        if (isset($column['length'])) {
            $mapping['length'] = $column['length'];
        }

        if (isset($column['precision'])) {
            $mapping['precision'] = $column['precision'];
        }

        if (isset($column['scale'])) {
            $mapping['scale'] = $column['scale'];
        }

        if (isset($column['unique'])) {
            $mapping['unique'] = (bool)$column['unique'];
        }

        if (isset($column['options'])) {
            $mapping['options'] = $column['options'];
        }

        if (isset($column['nullable'])) {
            $mapping['nullable'] = $column['nullable'];
        }

        if (isset($column['version']) && $column['version']) {
            $mapping['version'] = $column['version'];
        }

        if (isset($column['columnDefinition'])) {
            $mapping['columnDefinition'] = $column['columnDefinition'];
        }

        return $mapping;
    }

    /**
     * {@inheritDoc}
     */
    protected function loadMappingFile($file)
    {
        return Yaml::parse($file);
    }
}


text:
#pragma warning( disable:4800 )
#include <max.h>
#include "MAX_Mem.h"
#include <map>
#include "NifProps.h"
#include "iparamm.h"
#include "Simpobj.h"
#include "surf_api.h"
#include "notify.h"
#include "macroRec.h"
#include "bhkRigidBodyInterface.h"
#include "NifGui.h"
#include "NifStrings.h"
#include "bhkHelperFuncs.h"
#include <stdmat.h>
#include <meshdelta.h>
#ifndef _countof
#define _countof(x) (sizeof(x)/sizeof((x)[0]))
#endif

extern void compute_convex_hull(Mesh& mesh, Mesh& outmesh);

Class_ID BHKPROXYOBJECT_CLASS_ID = Class_ID(0x3f087788, BHKRIGIDBODYCLASS_DESC.PartB());
class ProxyPickObjectMode;

class bhkProxyValidatorClass : public PBValidator
{
public:
	class bhkProxyObject *mod;
private:
	BOOL Validate(PB2Value &v)
	{
		INode *node = (INode*) v.r;
		if (node->TestForLoop(FOREVER,(ReferenceMaker *) mod)!=REF_SUCCEED) return FALSE;

		ObjectState os = node->EvalWorldState(0);
		//Allow only tri object derived objects
		if (os.obj->CanConvertToType(triObjectClassID)  && os.obj->SuperClassID() != SHAPE_CLASS_ID) {
			return TRUE;
		}
		return FALSE;
	};
};

class bhkProxyObject : public SimpleObject2
{
	typedef SimpleObject2 BaseClass;
public:
   // Class vars
   IParamMap2 *pmapParam;
   IObjParam *ip;
   ProxyPickObjectMode *pickObMode;
   IParamMap2 *pbvParams[1]; //proxy
   Interface		*mIP;
   bhkProxyValidatorClass validator;
   ICustButton		*iPickButton;
   Mesh proxyMesh;
   Point3 proxyPos;
   bool forceRedraw;

   bhkProxyObject(BOOL loading);
   ~bhkProxyObject();

   // From Object
   int CanConvertToType(Class_ID obtype);
   Object* ConvertToType(TimeValue t, Class_ID obtype);
   void GetCollapseTypes(Tab<Class_ID> &clist,Tab<TSTR*> &nlist);

   CreateMouseCallBack* GetCreateMouseCallBack();
   void BeginEditParams( IObjParam  *ip, ULONG flags,Animatable *prev);
   void EndEditParams( IObjParam *ip, ULONG flags,Animatable *next);
   RefTargetHandle Clone(RemapDir& remap);
   TCHAR *GetObjectName() { return GetString(IDS_RB_PROXY); }

   int	NumParamBlocks() { return 1; }					// return number of ParamBlocks in this instance
   IParamBlock2* GetParamBlock(int i) { return pblock2; } // return i'th ParamBlock
   IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock2->ID() == id) ? pblock2 : NULL; } // return id'd ParamBlock

   // Animatable methods
   void DeleteThis() {delete this;}
   Class_ID ClassID() { return BHKPROXYOBJECT_CLASS_ID; }
   SClass_ID SuperClassID() { return HELPER_CLASS_ID; }

   // From SimpleObject
   void BuildMesh(TimeValue t);
   BOOL OKtoDisplay(TimeValue t);
   void InvalidateUI();

   int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags);

   void BuildEmpty();
   void BuildColBox();
   void BuildColStrips();
   void BuildColPackedStrips();
   void BuildColConvex();
   void BuildColCapsule();
   void BuildColOBB();
   void BuildOptimize(Mesh&mesh);

   void UpdateUI();
   void CreateMesh();

   Modifier *CreateWSMMod(INode *)
   {
	   return NULL;
   }
};

//--- ClassDescriptor and class vars ---------------------------------

// The class descriptor for box
class bhkProxyObjClassDesc : public ClassDesc2
{
public:
   bhkProxyObjClassDesc();
   int 			   IsPublic() { return 1; }
   void *			Create(BOOL loading = FALSE) {
      return new bhkProxyObject(loading);
   }
   const TCHAR *	ClassName() { return GetString(IDS_RB_PROXY_CLASS); }
   SClass_ID		SuperClassID() { return HELPER_CLASS_ID; }
   Class_ID		   ClassID() { return BHKPROXYOBJECT_CLASS_ID; }
   const TCHAR* 	Category() { return "NifTools"; }

   const TCHAR*	InternalName() { return _T("bhkProxyShape"); }	// returns fixed parsable name (scripter-visible name)
   HINSTANCE		HInstance() { return hInstance; }			// returns owning module handle
};

extern ClassDesc2* GetbhkProxyObjDesc();

// in prim.cpp  - The dll instance handle
extern HINSTANCE hInstance;

//--- Parameter map/block descriptors -------------------------------

// Parameter and ParamBlock IDs
enum { list_params, opt_params, clone_params, subshape_params };  // pblock2 ID
enum
{
   PB_MATERIAL, PB_MESHLIST, PB_BOUND_TYPE, PB_CENTER,
   PB_OPT_ENABLE, PB_MAXEDGE, PB_FACETHRESH, PB_EDGETHRESH, PB_BIAS,
   PB_LAYER, PB_FILTER,
};

enum { bv_type_none, bv_type_box, bv_type_shapes, bv_type_packed, bv_type_convex, bv_type_capsule, bv_type_obb };  // pblock ID

static ParamBlockDesc2 param_blk (
    list_params, _T("parameters"),  0, NULL, P_AUTO_CONSTRUCT + P_AUTO_UI + P_MULTIMAP, 0,
    //rollout
    4,
    list_params, IDD_PROXYPARAM1, IDS_PARAMS, 0, 0, NULL,
	opt_params,		IDD_RB_MOD_PANEL1, IDS_OPT_PARAMS, 0, 0, NULL,
	clone_params,	IDD_CLONE_PANEL,   IDS_CLONE_PARAMS, 0, 0, NULL,
	subshape_params,	IDD_RB_MOD_PANEL5,   IDS_LIST_SUBSHAPEPROPS, 0, 0, NULL,

    // params
    PB_MATERIAL, _T("material"), TYPE_INT, P_ANIMATABLE,	IDS_DS_MATERIAL,
      p_default,	NP_INVALID_HVK_MATERIAL,
      END,

    PB_BOUND_TYPE, 	_T("boundType"),	TYPE_INT, 0, IDS_BV_BOUNDING_TYPE,
	  p_default, 		0,
	  p_range, 			0, 5,
	  p_ui, 			list_params,	TYPE_RADIO, 7, IDC_RDO_NO_COLL, IDC_RDO_AXIS_ALIGNED_BOX, IDC_RDO_STRIPS_SHAPE, IDC_RDO_PACKED_STRIPS, IDC_RDO_CONVEX, IDC_RDO_CAPSULE, IDC_RDO_OBB,
	  END,

	PB_MESHLIST,   _T("meshProxy"),  TYPE_INODE_TAB,		0,	P_AUTO_UI|P_VARIABLE_SIZE,	IDS_MESHLIST,
	  p_ui,       list_params, TYPE_NODELISTBOX, IDC_LIST1,IDC_ADD,0,IDC_REMOVE,
	  END,

    PB_CENTER,   _T("center"),  TYPE_POINT3,  P_TRANSIENT,	IDS_CENTER,
	  END,

	PB_OPT_ENABLE,	_T("enableOptimize"), TYPE_BOOL, 0, IDS_OPT_ENABLE,
	  p_default, 	FALSE,
	  p_ui,			opt_params, TYPE_SINGLECHEKBOX, IDC_OPT_ENABLE,
	  END,

	PB_FACETHRESH,	_T("faceThresh"),	TYPE_FLOAT, P_RESET_DEFAULT, IDS_OPT_FACETHRESH,
	  p_default, 	0.1f,
	  p_range, 		0.0f, 90.0f,
	  p_ui,			opt_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_OPT_FACETHRESH, IDC_OPT_FACETHRESHSPIN, 0.01f,
	  p_uix,		opt_params,
	  END,

	PB_EDGETHRESH,		_T("edgeThresh"),		TYPE_FLOAT, 0, IDS_OPT_EDGETHRESH,
	  p_default, 	0.1f,
	  p_range, 		0.0f, 90.0f,
	  p_ui,			opt_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_OPT_EDGETHRESH, IDC_OPT_EDGETHRESHSPIN, 0.01f,
	  p_uix,		opt_params,
	  END,

	PB_BIAS,		_T("bias"),		TYPE_FLOAT, 0, IDS_OPT_BIAS,
	  p_default, 	0.1f,
	  p_range, 		0.0f, 1.0f,
	  p_ui,			opt_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_OPT_BIAS, IDC_OPT_BIASSPIN, 0.01f,
	  p_uix,		opt_params,
	  END,

	PB_MAXEDGE,		_T("maxEdge"),		TYPE_FLOAT, 0, IDS_OPT_MAXEDGE,
	  p_default, 	0.0f,
	  p_range, 		0.0f, 1000.0f,
	  p_ui,			opt_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_OPT_MAXEDGE, IDC_OPT_MAXEDGESPIN, SPIN_AUTOSCALE,
	  p_uix,		opt_params,
	  END,

	PB_LAYER, _T("layer"), TYPE_INT, P_ANIMATABLE,	IDS_DS_LAYER,
	  p_default,	NP_DEFAULT_HVK_LAYER,
	  END,

    PB_FILTER, _T("filter"), TYPE_INT, P_ANIMATABLE,	IDS_DS_FILTER,
	  p_default,	NP_DEFAULT_HVK_FILTER,
	  p_range, 		0, 255,
	  p_ui,			subshape_params, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_ED_FILTER, IDC_SP_FILTER, 0.01f,
	  p_uix,		subshape_params,
	  END,

    END
    );

// bug in pb desc? forces us to use this rather than in inline version
static bhkProxyObjClassDesc listDesc;
extern ClassDesc2* GetbhkProxyObjDesc() { return &listDesc; }
bhkProxyObjClassDesc::bhkProxyObjClassDesc() {
   param_blk.SetClassDesc(this);
}

class ProxyPickObjectMode :
	public PickModeCallback,
	public PickNodeCallback {
public:
	bhkProxyObject *mod;

	BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);
	BOOL Pick(IObjParam *ip,ViewExp *vpt);
	void EnterMode(IObjParam *ip);
	void ExitMode(IObjParam *ip);
	BOOL RightClick(IObjParam *ip,ViewExp *vpt)	{return TRUE;}
	BOOL Filter(INode *node);
	PickNodeCallback *GetFilter() {return this;}
};

//--- ProxyPickObjectMode ------------------------------------------------

BOOL ProxyPickObjectMode::Filter(INode *node)
{
	if (node) {
		node->BeginDependencyTest();
		mod->NotifyDependents(FOREVER,0,REFMSG_TEST_DEPENDENCY);
		if (node->EndDependencyTest()) {
			return FALSE;
		}
		////added code for looptest
		//if (node->TestForLoop(FOREVER,(ReferenceMaker *) mod)!=REF_SUCCEED)
		//   return FALSE;

		for (int i = 0;i < mod->pblock2->Count(PB_MESHLIST); i++) {
			INode *tnode = NULL;
			mod->pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
			if  (node == tnode)
				return FALSE;
		}

		ObjectState os = node->EvalWorldState(0);
		//added code such that lines are not selected
		if ( (os.obj->IsSubClassOf(triObjectClassID) || os.obj->CanConvertToType(triObjectClassID))
			&& (os.obj->SuperClassID() != SHAPE_CLASS_ID)
			)
		{
			return TRUE;
		}
		if (os.obj->SuperClassID() == HELPER_CLASS_ID && os.obj->ClassID().PartB() == BHKRIGIDBODYCLASS_DESC.PartB() ) {
			return TRUE;
		}
	}
	return FALSE;
}

BOOL ProxyPickObjectMode::HitTest(
							 IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags)
{
	INode *node = mod->mIP->PickNode(hWnd,m, this);	//added "this" argument such that the Filter above is used
	return node?TRUE:FALSE;
}

BOOL ProxyPickObjectMode::Pick(IObjParam *ip,ViewExp *vpt)
{
	BOOL rv = FALSE;
	if (INode *node = vpt->GetClosestHit()) {
		theHold.Begin();
		ObjectState os = node->EvalWorldState(0);
		if (os.obj->CanConvertToType(triObjectClassID)) {
			mod->pblock2->Append(PB_MESHLIST,1,&node,1);
			rv = TRUE;
		}
		theHold.Accept(GetString(IDS_ADD_MESH));
	}
	return rv;
}

void ProxyPickObjectMode::EnterMode(IObjParam *ip)
{mod->iPickButton->SetCheck(TRUE);}

void ProxyPickObjectMode::ExitMode(IObjParam *ip)
{mod->iPickButton->SetCheck(FALSE);}

static ProxyPickObjectMode thePickMode;

class ProxyParamDlgProc : public ParamMap2UserDlgProc {
public:
   bhkProxyObject *so;
   HWND thishWnd;
   NpComboBox		mCbMaterial;

   ProxyParamDlgProc(bhkProxyObject *s) {so=s;thishWnd=NULL;}
   INT_PTR DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
   void Update(TimeValue t);
   void DeleteThis() {delete this;}

   //--- ParamDlgProc --------------------------------
   void TurnSpinner(HWND hWnd,int SpinNum,BOOL ison)
   {
      ISpinnerControl *spin2 = GetISpinner(GetDlgItem(hWnd,SpinNum));
      if (ison) spin2->Enable();else spin2->Disable();
      ReleaseISpinner(spin2);
   };

};

void ProxyParamDlgProc::Update(TimeValue t)
{
   if (!thishWnd)
      return;
   return;
}

INT_PTR ProxyParamDlgProc::DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
   thishWnd=hWnd;
   switch (msg)
   {
   case WM_INITDIALOG:
      {
		  mCbMaterial.init(GetDlgItem(hWnd, IDC_CB_MATERIAL));
		  mCbMaterial.add("<Default>");
		  for (const char **str = NpHvkMaterialNames; *str; ++str)
			  mCbMaterial.add(*str);
		  Interval valid;
		  int sel = NP_INVALID_HVK_MATERIAL;
		  so->pblock2->GetValue( PB_MATERIAL, 0, sel, valid);
		  mCbMaterial.select( sel + 1 );
		 // Disable all types not currently implemented
		  EnableWindow(GetDlgItem(hWnd, IDC_RDO_CAPSULE), CanCalcCapsule() ? TRUE : FALSE);
		  EnableWindow(GetDlgItem(hWnd, IDC_RDO_OBB), CanCalcOrientedBox() ? TRUE : FALSE);
		 //EnableWindow(GetDlgItem(hWnd, IDC_RDO_PACKED_STRIPS), FALSE);

         Update(t);
         break;
      }
   case WM_DESTROY:
	   if (so && so->iPickButton != NULL) {
		   ReleaseICustButton(so->iPickButton);
		   so->iPickButton = NULL;
	   }
	   break;

   case WM_COMMAND:
      switch (LOWORD(wParam))
      {
      case IDC_CB_MATERIAL:
         if (HIWORD(wParam)==CBN_SELCHANGE) {
            so->pblock2->SetValue( PB_MATERIAL, 0, mCbMaterial.selection() - 1 );
         }
         break;

	  case IDC_BTN_CLONE:
		  so->CreateMesh();
		  break;
      }
      break;
   }
   return FALSE;
}

namespace
{
	class CloneMeshDlgProc : public ParamMap2UserDlgProc {
	public:
		bhkProxyObject *mod;
		CloneMeshDlgProc(bhkProxyObject* m) {mod = m;}
		void DeleteThis() {delete this;}

		INT_PTR DlgProc (TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
		{
			switch (msg)
			{
			case WM_COMMAND:
				switch (LOWORD(wParam))
				{
				case IDC_BTN_CLONE:
					mod->CreateMesh();
					return TRUE;

				default:
					return FALSE;
				}
			}
			return FALSE;
		}
	};

	// Controller for subshape properies: layer and filter
	class SubShapeDlgProc : public ParamMap2UserDlgProc {
	public:
		bhkProxyObject *mod;
		NpComboBox		mCbLayer;
		SubShapeDlgProc(bhkProxyObject* m) {mod = m;}
		INT_PTR DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
		void DeleteThis() {delete this;}
	};

	INT_PTR SubShapeDlgProc::DlgProc (TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
	{
		switch (msg)
		{
		case WM_INITDIALOG:
			{
				mCbLayer.init(GetDlgItem(hWnd, IDC_CB_LAYER));
				for (const char **str = NpHvkLayerNames; *str; ++str)
					mCbLayer.add(*str);

				int sel = NP_DEFAULT_HVK_LAYER;
				Interval valid;
				mod->pblock2->GetValue( PB_LAYER, 0, sel, valid);
				mCbLayer.select( sel );

				Update(t);
				break;
			}

		case WM_DESTROY:
			break;

		case WM_COMMAND:
			switch (LOWORD(wParam))
			{
			case IDC_CB_LAYER:
				if (HIWORD(wParam)==CBN_SELCHANGE) {
					mod->pblock2->SetValue( PB_LAYER, 0, mCbLayer.selection() );
				}
				break;

			default:
				return FALSE;
			}
		}
		return FALSE;
	}
}

//--- Proxy methods -------------------------------

bhkProxyObject::bhkProxyObject(BOOL loading)
{
	pmapParam = NULL;
	ip = NULL;
	pickObMode = NULL;
	pbvParams[0] = NULL;
	mIP = NULL;
	iPickButton = NULL;
	validator.mod = this;
	forceRedraw = false;

   SetAFlag(A_PLUGIN1);
   listDesc.MakeAutoParamBlocks(this);
   assert(pblock2);
}

bhkProxyObject::~bhkProxyObject()
{
   param_blk.SetUserDlgProc();
   if (pmapParam) {
      pmapParam  = NULL;
   }
}

void bhkProxyObject::BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev)
{
   BaseClass::BeginEditParams(ip,flags,prev);
   mIP = ip;

   listDesc.BeginEditParams(ip,this,flags,prev);
   param_blk.SetUserDlgProc(new ProxyParamDlgProc(this));
   param_blk.SetUserDlgProc(clone_params, new CloneMeshDlgProc(this));
   param_blk.SetUserDlgProc(subshape_params, new SubShapeDlgProc(this));
   pmapParam = pblock2->GetMap(list_params);

   this->ip = ip;
}

void bhkProxyObject::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
{
   param_blk.SetUserDlgProc();

   BaseClass::EndEditParams(ip,flags,next);
   this->ip = NULL;
   pmapParam = NULL;

   if (iPickButton != NULL) {
	   ReleaseICustButton(iPickButton);
	   iPickButton = NULL;
   }

   // tear down the appropriate auto-rollouts
   listDesc.EndEditParams(ip, this, flags, next);
   mIP = NULL;
}

void bhkProxyObject::UpdateUI()
{
   if (ip == NULL)
      return;
   ProxyParamDlgProc* dlg = static_cast<ProxyParamDlgProc*>(pmapParam->GetUserDlgProc());
   dlg->Update(ip->GetTime());
}

enum
{
   POSX = 0,	// right
   POSY = 1,	// back
   POSZ = 2,	// top
   NEGX = 3,	// left
   NEGY = 4,	// front
   NEGZ = 5,	// bottom
};

void bhkProxyObject::BuildMesh(TimeValue t)
{
	ivalid = FOREVER;

	int bvType = 0;
	pblock2->GetValue(PB_BOUND_TYPE, 0, bvType, FOREVER, 0);

	BuildEmpty();

	switch (bvType)
	{
	default:
	case bv_type_none:
		// Delete mesh.
		break;

	case bv_type_box: // box
		BuildColBox();
		break;

	case bv_type_shapes: // Shapes
		BuildColStrips();
		//BuildBox(mesh,,,)
		break;

	case bv_type_packed: // Packed
		BuildColPackedStrips();
		//BuildSphere();
		break;

	case bv_type_convex:
		BuildColConvex();
		//BuildScubaMesh();
		break;

	case bv_type_capsule:
		BuildColCapsule();
		break;

	case bv_type_obb:
		BuildColOBB();
		break;
	}
}

Object* bhkProxyObject::ConvertToType(TimeValue t, Class_ID obtype)
{
	if (obtype == triObjectClassID)
	{
		int bvType = 0;
		pblock2->GetValue(PB_BOUND_TYPE, 0, bvType, FOREVER, 0);
		if (bvType != 0)
		{
			TriObject *ob = CreateNewTriObject();
#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+
			ob->GetMesh().CopyBasics(proxyMesh);
#else
			ob->GetMesh() = proxyMesh;
#endif
			ob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t));
			ob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t));
			return ob;
		}
	}
	return 0;
}

int bhkProxyObject::CanConvertToType(Class_ID obtype)
{
	if (obtype == triObjectClassID) {
		int bvType = 0;
		pblock2->GetValue(PB_BOUND_TYPE, 0, bvType, FOREVER, 0);
		return (bvType != 0) ? TRUE : FALSE;
	}
	return FALSE;
}

void bhkProxyObject::GetCollapseTypes(Tab<Class_ID> &clist,Tab<TSTR*> &nlist)
{
   Object::GetCollapseTypes(clist, nlist);
}

class ProxyObjCreateCallBack: public CreateMouseCallBack {
   bhkProxyObject *ob;
   Point3 p0,p1;
   IPoint2 sp0, sp1;
   BOOL square;
public:
   int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat );
   void SetObj(bhkProxyObject *obj) { ob = obj; }
};

int ProxyObjCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) {
   Point3 d;
   if (msg == MOUSE_FREEMOVE)
   {
      vpt->SnapPreview(m,m,NULL, SNAP_IN_3D);
   }

   else if (msg==MOUSE_POINT||msg==MOUSE_MOVE) {
      switch(point) {
         case 0:
            // Find the node and plug in the wire color
            {
               ULONG handle;
               ob->NotifyDependents(FOREVER, (PartID)&handle, REFMSG_GET_NODE_HANDLE);
               INode *node = GetCOREInterface()->GetINodeByHandle(handle);
               if (node) node->SetWireColor(RGB(255, 0, 0));
            }

            sp0 = m;
            //ob->suspendSnap = TRUE;
            p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_3D);
            p1 = p0 + Point3(.01,.01,.01);
            mat.SetTrans(float(.5)*(p0+p1));

			ob->pmapParam->Invalidate();

            if (msg==MOUSE_POINT)
            {
               //ob->suspendSnap = FALSE;
               return CREATE_STOP;
            }
            break;
      }
   }
   else
      if (msg == MOUSE_ABORT) {
         return CREATE_ABORT;
      }

      return TRUE;
}

static ProxyObjCreateCallBack listCreateCB;

CreateMouseCallBack* bhkProxyObject::GetCreateMouseCallBack()
{
   listCreateCB.SetObj(this);
   return(&listCreateCB);
}

BOOL bhkProxyObject::OKtoDisplay(TimeValue t)
{
   return TRUE;
}

void bhkProxyObject::InvalidateUI()
{
   param_blk.InvalidateUI(pblock2->LastNotifyParamID());
   if (pmapParam) pmapParam->Invalidate();
}

RefTargetHandle bhkProxyObject::Clone(RemapDir& remap)
{
   bhkProxyObject* newob = new bhkProxyObject(FALSE);
   newob->ReplaceReference(0,remap.CloneRef(pblock2));
   newob->ivalid.SetEmpty();
   BaseClone(this, newob, remap);
   return(newob);
}

int bhkProxyObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
{
	if (forceRedraw)
	{
		Interface *gi = GetCOREInterface();
		gi->ForceCompleteRedraw();
	}

	Matrix3 m;
	Color color = Color(inode->GetWireColor());
	GraphicsWindow *gw = vpt->getGW();
	Material *mtl = gw->getMaterial();
	m = inode->GetObjectTM(t);
	gw->setTransform(m);
	DWORD rlim = gw->getRndLimits();

	DWORD newrlim = GW_WIREFRAME|GW_Z_BUFFER;
#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+
	newrlim |= GW_EDGES_ONLY;
#endif
	gw->setRndLimits(newrlim);

	if (inode->Selected())
		gw->setColor( LINE_COLOR, GetSelColor());
	else if(!inode->IsFrozen() && !inode->Dependent())
		gw->setColor( LINE_COLOR, color);

	Matrix3 m3(true);

	float size = 20.0f;
	Point3 pts[5];
	// X
	pts[0] = Point3(-size, 0.0f, 0.0f); pts[1] = Point3(size, 0.0f, 0.0f);
	vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);

	// Y
	pts[0] = Point3(0.0f, -size, 0.0f); pts[1] = Point3(0.0f, size, 0.0f);
	vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);

	// Z
	pts[0] = Point3(0.0f, 0.0f, -size); pts[1] = Point3(0.0f, 0.0f, size);
	vpt->getGW()->polyline(2, pts, NULL, NULL, FALSE, NULL);

	//UpdateMesh(t);

	int bvType = 0;
	pblock2->GetValue(PB_BOUND_TYPE, 0, bvType, FOREVER, 0);
	if (bvType != 0)
	{
		Matrix3 tm = gw->getTransform();
		Matrix3 proxyTM(true);
		proxyTM.SetTranslate(proxyPos);
		gw->setTransform(proxyTM);
		proxyMesh.render( gw, mtl, NULL, COMP_ALL);
		gw->setTransform(tm);
	}
	gw->setRndLimits(rlim);
	return 0;
}

void bhkProxyObject::BuildEmpty()
{
	BuildBox(mesh, 10.0f, 10.0f, 10.0f);
	proxyMesh.FreeAll();
	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildColBox()
{
	Box3 box; box.Init();
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Box3 box2; box2.Init();
				Mesh& mesh = tri->GetMesh();
				CalcAxisAlignedBox(mesh, box2, &wm);
				box += box2;
			}
		}
	}
	BuildBox(proxyMesh, box.Max().y-box.Min().y, box.Max().x-box.Min().x, box.Max().z-box.Min().z);

	MNMesh mn(proxyMesh);
	Matrix3 tm(true);
	tm.SetTranslate(box.Center());
	mn.Transform(tm);
	mn.OutToTri(proxyMesh);

	//proxyPos = box.Center();
	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildColStrips()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	BuildOptimize(proxyMesh);
	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildColPackedStrips()
{
	BuildColStrips();
}

void bhkProxyObject::BuildColConvex()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	compute_convex_hull(proxyMesh, proxyMesh);

	BuildOptimize(proxyMesh);

	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildColCapsule()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	Point3 pt1 = Point3::Origin;
	Point3 pt2 = Point3::Origin;
	float r1 = 0.0;
	float r2 = 0.0;

	if (proxyMesh.getNumVerts() > 3) // Doesn't guarantee that the mesh is not a plane.
	{
		CalcCapsule(proxyMesh, pt1, pt2, r1, r2);
		BuildCapsule(proxyMesh, pt1, pt2, r1, r2);
	}

	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildColOBB()
{
	proxyMesh.FreeAll();
	MeshDelta md(proxyMesh);
	for (int i = 0;i < pblock2->Count(PB_MESHLIST); i++) {
		INode *tnode = NULL;
		pblock2->GetValue(PB_MESHLIST,0,tnode,FOREVER,i);
		if (tnode)
		{
			ObjectState os = tnode->EvalWorldState(0);
			Matrix3 wm = tnode->GetNodeTM(0);
			TriObject *tri = (TriObject *)os.obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0));
			if (tri)
			{
				Mesh& mesh = tri->GetMesh();
				MeshDelta tmd (mesh);
				md.AttachMesh(proxyMesh, mesh, wm, 0);
				md.Apply(proxyMesh);
			}
		}
	}
	Matrix3 rtm(true);
	Point3 center = Point3::Origin;;
	float udim = 0.0f, vdim = 0.0f, ndim = 0.0f;

	if (proxyMesh.getNumVerts() > 3) // Doesn't guarantee that the mesh is not a plane.
	{
		// First build a convex mesh to put the box around;
		// the method acts oddly if extra vertices are present.
		BuildColConvex();
		CalcOrientedBox(proxyMesh, udim, vdim, ndim, center, rtm);
		BuildBox(proxyMesh, vdim, udim, ndim);
	}

	MNMesh mn(proxyMesh);
	mn.Transform(rtm);
	mn.OutToTri(proxyMesh);

	proxyPos = Point3::Origin;
	forceRedraw = true;
}

void bhkProxyObject::BuildOptimize(Mesh& mesh)
{
	BOOL enable = FALSE;
	pblock2->GetValue(PB_OPT_ENABLE, 0, enable, FOREVER, 0);
	if (enable)
	{
		float maxedge, facethresh, edgethresh, bias;
		pblock2->GetValue(PB_MAXEDGE, 0, maxedge, FOREVER, 0);
		pblock2->GetValue(PB_FACETHRESH, 0, facethresh, FOREVER, 0);
		pblock2->GetValue(PB_EDGETHRESH, 0, edgethresh, FOREVER, 0);
		pblock2->GetValue(PB_BIAS, 0, bias, FOREVER, 0);

		DWORD flags = OPTIMIZE_AUTOEDGE;
		mesh.Optimize(facethresh, edgethresh, bias, maxedge, flags, NULL);
	}
}

void bhkProxyObject::CreateMesh()
{
	if (Interface *gi = this->mIP)
	{
		if (const Mesh* pMesh = &this->proxyMesh)
		{
			if (TriObject *triObject = CreateNewTriObject())
			{
				MNMesh mnmesh(*pMesh);
				Mesh& mesh = triObject->GetMesh();
				mnmesh.OutToTri(mesh);

				INode *node = gi->CreateObjectNode(triObject);
				// Wireframe Red color
				StdMat2 *collMat = NewDefaultStdMat();
				collMat->SetDiffuse(Color(1.0f, 0.0f, 0.0f), 0);
				collMat->SetWire(TRUE);
				collMat->SetFaceted(TRUE);
				gi->GetMaterialLibrary().Add(collMat);
				node->SetMtl(collMat);

				node->SetPrimaryVisibility(FALSE);
				node->SetSecondaryVisibility(FALSE);
				node->BoneAsLine(TRUE);
				node->SetRenderable(FALSE);
				node->SetWireColor( RGB(255,0,0) );

				gi->SelectNode(node);
			}
		}
	}
}