Sunday, August 7, 2011

All that glitters isn't Drupal : CMS vs Framework

While I'm using Drupal on some projects as an example, I'm not singling Drupal out for criticism for the sake of it, and not ignorantly either as it's the CMS I have most production project experience with (opposed to vBulletin, though when I worked creating that, it was a forum - and not trying to be anything else).

The purpose of this post has to do with my thoughts on : Choosing the right tool (and starting point) for the job.

Knowing not only why, but that you have done so, as no project or pieces of software is ever "done" till two things happen. Firstly when it's stopped being worked on, and then it will last as long as it is robust, and secondly when the server is turned off.

Everything from conception up to the first stage is "the development of a software system", releasing it or putting it on a server is just one part of that, typically when customers (hopefully turn up and) need supporting. It's also usually at this point that if you have community engagement and it's manage that your system can be lead and developed for the needs of the community that want and use it. Release too early and you wont have enough of a vision or direction, too late and you'll of cut off all kinds of possible user input. Also someone else might of beat you to market.

So what does this have to do with a CMS like Drupal and a Framework ?

Much the same difference that buying Ikea furniture has with buying precut wood and understanding the tools. As always there is a time and place for both, though two typical things happen when you have a CMS build vs a framework build.

First ....... explosive module bloat. I can't remember the number of times I heard the conversation :

"Oh I just want to do this one simple thing"
"It's OK I know of one module that does that, though you need five other to support it, but hey that's OK".

A few weeks later you have two hundred SQL queries per page load and 70 modules, just for an original request of one simple feature. Given that it's very likely that you're relying on 3rd party modules, you are now at the mercy of the erratic OSS winds for the up keep of the module(s).

Typically you'll never get the exact behaviour you want as any generic module is built to what ever the requirements were at the time the author write them, so likely a compromise to what ever it is you need now.

The typical approach I've seen to this in the vast majority of Drupal projects is "Time to do some integration work" ....... also known as ....... "Just keep hacking it till it seems to work" i.e  open window throw out quality and stability and upgrade path, close window.

When this approach inevitably grinds to a halt you end up seeing the "Need a rock star Drupal developer for final 10% of project" posts on job boards. At this point  you know it's a spaghetti nightmare ....... the irony of why not get a "rock solid engineer" to begin with is never lost on me.

Second thing is maintenance, or full life cycle support. i.e. once you get to market and have to care for and evolve the system, you can't. You're so hacked into a corner the technical debt overwhelms anything you can do against it. This is typically where inept management will start to blame developers for their choices when faced with the symptoms of a system in crisis.


So what goes wrong ?

1) Due diligence

A software system as we've seen is a journey. Even with my recent encounters with the games industry and individuals claiming something is "done" and should be launched, it's not, there will be patches and updates. They are just trying to minimise the latter and try to paint it as failure opposed to understanding that it's part of the process.

Obviously embedded systems in medical equipment (as an example) is a different story, though it's very much the process and understanding which is present that achieves that level of quality, so actually supports my argument.

So ensuring that you (as a client) know what the options are, or as a developer are skilled enough to communicate that to a client is essential. If you aren't go work for someone who is, and learn from them.

Are you building a product or site to depend upon or a site for a weekend event that is going to be decommissioned in a few days. One needs good foundations and the other needs speed. Understand that rapid prototyping is just that, prototyping, it's done for learning (as is the blend of development by exploration) not delivery.

Typically what happens is that speed is chosen and high quality is assumed, opposed to the reality which is the other way around.

Speed in this context is the wrong word as well - it should be velocity as that has a direction which is important and it encompasses the vision of an outcome as well as time.

Answer - Don't just do something - think first - where is this going and what does it have to do.

2) Been told vs choosing

Requirements and understanding of the problem, then the tools not the other way around. I've met with teams that seems to think that there is a one word answer to every project (i.e. Drupal). Open blog site ? Drupal ...... image upload site ? Drupal ...... hot metal device for flattening my freshly cleaned clothes ..... you guessed it, Drupal.

Fanaticism leads to blindness, not just in politics and religion, but in engineering as well.

Answer - Realise you're in a very diverse world, and that's a good thing. There is no one answer to everything how ever hard you want it to be, as every situation is different.


When to use one over the other ?

By taking the time to understand, how well do you know what it is that you want to achieved, what are your time scales and will this every have to be maintained.

Given the 80/20 rule applies to most software projects using something like Drupal do do 100%, getting the 80% done quickly and then hacking yourself into a corner to get the last 20% isn't worth it ....... given that you can do the 20% with a half decent frame work anyway.


Other reading :

Thursday, March 3, 2011

How to create SugarCRM graphs

Creating New Sugar CRM Graphs

I've recently been working on a project that required some custom chart additions to SugarCRM. At time of writing the project is using the Community Edition, which according to wikipedia has 85%~ of the code base that the Professional and Enterprise editions do.

I think I'll have to side with Dan Farber from CNET with concerns over how SugarCRM uses the term Open Source - it's not really. Especially considering that I'm working with the charts module, which is one of the main pieces which has been removed from the AGPLv3 license in Sugar 6 (the latest edition).

While being hindered by a lack of documentation and examples with regard to charting, i.e. the main way you view all the data in your system, I've had to reverse engineer the system that is being used. This would appear to be common in various areas of CE, i.e. it's entry point bait that gets you going on a project - then you realise you need Pro or Enterprise - to deliver on the project.

Make sure you have all the functionality asses before you start on a project with this, and if you can't find how to do something in less that two minuets, assume it can't be done.

I think a better route would of been to use something like CodeIgnighter and jpGraph and build a custom reporting interface. Opposed to using the limitations of the Flash graph player that is offered by default. Then again if your off down that route you're already - outside of the bounds of the system - you should be looking at the whole project and what fits best, as it might not be SugarCRM at all.

Though this blog is about explaining how the parts I understand interact, and then how to work with what is there.


SugarCRM uses the concept of modules, and modules can have "Dashlets" which is what you can see and interact with on your Dashboard. For this example we'll be in the directory :


Fairly self explanatory so far - the dashlets directory for the charts module.

There are several predefined ones in there.

Ultimately the Chart Dashlet is a Flash player that is given the URL to a PHP generated XML file, which then renders it as the graph you see.

The files in a Dashlet folder are named as per the folder and class name (as that's how Sugar finds and loads the relevant classes).

So for our example we'll have :


A chart to show the total accounts we have per month.

Inside that directory there are 5 files (yes 5 .....) that make up the data/functions for the chart :

  1. {name}.data.php
  2. {name}.en_us.lang.php
  3. {name}.meta.php
  4. {name}.php 
  5. {name}.tpl

So for our chart we'll have :

  2. AccountsTotal.en_us.lang.php
  3. AccountsTotal.meta.php
  4. AccountsTotal.tpl
  5. AccountsTotal.php

Just copy one of the existing directories and files, and then rename them.

This will contain the search fields for the chart, the popup when you click on edit to choose a date etc. For now just rename the first element of the Array to the class name so Sugar can load it .

$dashletData['AccountsTotal']['searchFields'] = array(


Same again here, it's just a tokened language file, so rename the key to the class name

$dashletStrings['AccountsTotal'] = array(


The meta file is used (for what we're concerned with) by the Dashlet selector - the pop up where you select what Dashlets you want to add to your Dashboard. If you want to check the options the images are stored in :


i.e. icon_Charts_GroupBy_32.gif


The template file you can leave for now, it's the HTML for the configure popup, i.e. where you choose the dates to feed to the graph logic.


This is the main file for the graphs, the C of the MVC world.

This is a class file that extends the Sugar class of - DashletGenericChart - so rename accordingly.

class AccountsTotal extends DashletGenericChart

The constructor and displayOptions can be left, and just call the parent methods. The $options that are passed to the constructor are the details that you set in the search fields.

public function __construct($id, array $options = null)
public function displayOptions()
  return parent::displayOptions();

The final two methods are the constructQuery() and display(), the query function is just an abstraction for generating the SQL, applying variables from globals or passed in options etc.

The display method is the main area you need to be concerned with, overriding the parent and adding in all the XML generation, saving then loading of flash player and passing of XML URL.

There is an include to get the chartDefs, the the actual sugarchart is created and properties set :


$sugarChart = new SugarChart();

    /* Title */    "My charts title",
    /* Subtitle */ "Some relevant sub title",
    /* Type */     $chartDef['chartType']

The signature is :

setProperties($title, $subtitle, $type, $legend = 'on', $labels = 'value', $print = 'on')

There are some defaults of the chat class set in the original, that I've just left :

$sugarChart->base_url = $chartDef['base_url'];
$sugarChart->group_by = $chartDef['groupBy'];
$sugarChart->url_params = array();

Now to get the data & construct the XML I have deviated from Sugar, as after decompling the SWF file and going though the XML generation (that is string building opposed to any use of native PHP XML) I found a much easier and quicker route to getting the job done.

There are also various bugs and inconsistencies around :


So I didn't use it, I wrote my own XML handler available (here), it constructs the XML using native PHP functions to do so.

All that remains is to get the data, and sort it, getData() seems to work, so we can use that.


This places the data into an array :


All that remains to sort the query data into rawData then use the new XML class to build the desired outcome and then pass it to the usual Sugar methods for saving the XML and returning the HTML to display the Dashlet.

The final 3 lines of the method do all of that :

 return $this->getTitle(...

As per SugarCRM community killing conventions I have omitted  any comments and anything that could be helpful from the source ;)

And here is the display method :

public function display()
    $currency_symbol = $GLOBALS['sugar_config']['default_currency_symbol'];

    if ($GLOBALS['current_user']->getPreference('currency'))
        $currency = new Currency();
        $currency_symbol = $currency->symbol;


    $chartDef = $chartDefs['outcome_by_month'];


    $sugarChart = new SugarChart();

        /* Title */    "Total GLA By Month :: {$this->startDate} to  {$this->endDate}",
        /* Subtitle */ "Month view",
        /* Type */     $chartDef['chartType']

    $sugarChart->base_url = $chartDef['base_url'];
    $sugarChart->group_by = $chartDef['groupBy'];
    $sugarChart->url_params = array();

    $rawData = array();
    $month = array (
        1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'May', 6 => 'Jun',
        7 => 'Jul', 8 => 'Aug', 9 => 'Sep', 10 => 'Oct', 11 => 'Nov', 12 => 'Dec'
    for($i = 1; $i <= 12; $i++)
        $rawData[$i] = array('title' => $month[$i], 'value' => 0, 'label' => 0);
    $value = 0;
    foreach ($sugarChart->data_set AS $id => $details)
        $value = ($details['total'] > 0 ? $details['total'] : 0);
        $rawData[$details['month']]['value'] = $details['total'];
        $rawData[$details['month']]['label'] = $details['total'];
    $options['properties'] = array (
        'title'    => "Accounts By Month",
        'subtitle' => 'Months',
        'type'     => 'bar chart',
        'legend'   => 'off',
        'labels'   => 'value'

    $options['ystep']= 100;
    $x = new XMLGraph($options);

    if ($value)
        $total = $this->previousAccountTotal();
        foreach ($rawData AS $monthId => $monthData)
            $total += $monthData['value'];
            if ($monthData['value'] AND $total)
                $monthData['value'] = $total;
                $monthData['label'] = $total;

        $testXML = $x->asXML();
        $testXML = $x->emptyXML();

    $sugarChart->saveXMLFile($xmlFile, $testXML);

    return $this->getTitle('

') . '
' . $sugarChart->display($this->id, $xmlFile, '100%', '460', false) . '
<br />';


A messy work around for sure, though gets the job done for the various graph types I've deciphered so far. I'll add more as I do and likely create a whole repo for a default graph.

As for calling SugarCRM open source ....... it might be stepping on or right up to the line in legal terms - though I don't think it is wholly OSS in the spirit of the movement.

I hope it decides what camp it is in and announces that sooner rather than later.

Sunday, January 30, 2011

What is :: Hackmode - Flow - The Zone

I've always been interested not only in the specifics of software itself, but also  in the method of how software is created, and what surrounds it. That being teams, leadership, management, external factors, business constraints and likely most importantly the sociology and psychology of creation.

More of a holistic systems view of the whole process I believe.  My degree and area of interest is Software Engineering Management so some of the how as well as the what.

I realised I've found myself explaining the same topic repeatedly to people in a business context (i.e. suits) who don't develop software, but who interact with people who do.

So I thought it best to just write it up, then I can direct future people I encounter who ask or need to understand it to here. Also share my thoughts and hope to elicit ideas and experience from others, as this topic really interests me.

The topic is that of the psychology of a developer, when operating a maximum capacity (relative to them). What's it like, how do people get there and what are the good and bad aspects of it.

Typically I find organisations (mid level managers usually) expect and demand maximum output of developers at all times, in any conditions and with no support. Any failure to achieve this with a (typically) negative or unsupported environment is wholly the developers fault (see my other post on burnout for what happens then !).

The usual analogy for that situation is a Dickensian work house, where more hours and faster (more frantic speed) should equate to more output.

Obviously nonsense, though still lots of places like that about, and it's all of our responsibilities to eradicate them.


The Mind Set

The mind set of a developer when at maximum level of creation and development is covered by an area of : Positive Psychology. in particular "Flow".

Introduced by Mihály Csíkszentmihályi it is a well accepted description and understanding of the mental state of individuals, who are wholly engaged and passionate about an activity they are doing. There have been many posts on passion in developers being one of the main things, and I agree (we just need to educate recruiters now).

The wiki page for Flow covers a lot of the general aspects of the topic, so I'd like to relate/translate that to software creation and teams. The page does mention professionals and references Hack Mode and The Zone.

One way that I attempt to explain the state of being in Flow to people who haven't been, or can't understand it in a developers context is to reference Star Trek Generations. While a techie film itself, it's still more likely to have been seen by someone I'm explain to, than them reading psychology just for fun.

In the movie there is a character, Soran (Dr. Tolian), played by Malcolm McDowell (yes, I know he must be the evil baddie he's English .......)  who is attempting to get back into the Nexus.

The Nexus is described as :

"The Nexus is an extra dimensional realm in which one's thoughts and desires shape reality."

by (which is one of the better descriptions I've heard).

This is a fairly fanciful analogy I'll admit. Though there are a lot of comparisons of being in an place/zone where everything you can think of just happens, where you laugh at test units and write and re-write swathes of class/functions in moments. Code of pure gold flows from the keyboard etc.

And it's a true pleasure, not only are you creating at a pace that would make accountants shiver when calculating your hourly rate vs effectiveness.

Though far far more importantly, you are doing what you enjoy and are feeling the rewards of creativity near instantly. Maslow would likely describe  you as in a state of : Self-actualization.

For me there is no reward, monetary incentive or management manipulation that can either induce this, or surpass the reward of experience itself (though for sure I'll accept a health pay check/equity for it when it does happen !).

I'm not sure I'd destroy a planet and it's people (as Soran was prepared too), to get back to it on demand, though I'd think about it ........

Though it raises two very interesting points for me :
  • How do you get there ? 
  • How do you stay there ?


Allowing it to happen

Personally (and in the research I've done) the path must include a level of passion and/or very high engagement. This typically can't be demanded by management or forced onto a person.

It's much like (my aversion to) the TV self-help demagogues, who are forever telling (prescribing to) people how to live, opposed to the people creating and embodying the answers for themselves.

In counselling, it's called client centered. Zen and other eastern philiosphys continually talk about the energy and power within, and that's where the source of a lot of this comes from.

The main thing that management, and more suitable team facilitator(s) can do, is create and protect the environment to allow the developer(s) to reach this state. Once that is in place, communicate the challenge/goal and desired outcome, then stand back and get out of the teams way. Ego is the typical reason this doesn't happen as weak management has to feel "in control". A shame, though a common human failing.

Attaining Flow is a skill and ability, it comes from engagement, curiosity, the challenge and having the skills to overcome the task.

Meaning you have to be good enough for the challenge, that you're not battling with your tools. Be that, a programming language, the server configuration, understanding of a protocol etc.

So the things needed are :
  • A sufficient challenge, it's engaging and enticing
  • You have to be "up for it", personal motivation and external encouragement
  • Have sufficient skills enough "to take it on", and not be over whelmed

As per the diagram (I grabbed from wikipedia) :

Staying there for the individual is a matter of practice, of concentration and immersion. Much like practicing to meditate, I remember when I started meditating I would last two maybe three minuets and my mind would wander, years later and half an hour is no real challenge within itself (more so the motivation to actually begin now !).

Staying There

I find the single most important piece in a development environment that is lacking, is the understanding of the other individuals (hence writing this so I don't have to keep repeating myself).

It can take any where from 15-30 mins for an individual get into this state, and become engaged and start producing while there. The constant inquiries of "Have you done it yet" or "Lets all have a meeting to listen to me talk" is doing nothing but breaking that lead in time, and hitting the reset switch for getting back into it. I'm all for communication, of course, teams and organisations need it. Though when necessary and in context.

I think the only thing that is more disruptive (and mentally painful) from being stopped getting to the Nexus ....... err a productive state of mind ..... is being ripped out of it once there. It's so jarring I've contemplated drowning people before ..... though have put it down to their ignorance opposed to malice.

Nerf guns in an office are for play time ........ not 24/7 while people are trying to work.

Shouting into phones in (or at people on the other side of) an open office (which themselves are very negative to focusing) isn't helping.

Typical management is driven by interruption, Jason Fried 37signals has talked about interruptions lately, and way pre-dating him is Peopleware that covers it in much more detail.


Personally I become very frustrated when subjected to the kind of environment that stops productivity and high quality productivity at that.

I (and just about all developers I've ever talked to) can do far more in 4 Flow hours than 8 of typical office, and it's far better for everyone involved. Let alone the future as the software is of a much higher quality : think lower Technical Debt.

So why not let it happen and protect it ?

As ever take care of #1 and have a thought for others trying to get things done.


P.S. The statistical support of this is here

Tuesday, January 18, 2011

Dealing with challenging behaviour in IT groups

I recently saw a few tweets pushing a piece entitled : When Smart People are Bad Employees.

Luckily the sense of many comments shone though, and the author was eviscerated for what appeared to be short sightedness, poor understanding of behaviour and basically poor posting.

Though it did get me thinking about the amount of confusion and reactionary behaviour there is out there by this kind of management, which that author appears to be representative off (thankfully small and diminishing in my experience, though still present).

Another case of trying to enforce "us and them" I'm right your wrong, opposed to "we".

We're all human, and we're all fallible at times.

I found the majority of this kind of behaviour and approach comes from a lack of trust, of oneself mostly, and then the team. A fear response to attempt to control, opposed to having the will power and self control to resist such behaviour.

(There was another piece I saw on : Managing Nerds, while better and nearly saving itself with some tongue in cheek humour, it was ultimately "us and them" tactics as well as being simplistic and condescending)

Hence why I'm going to review some of the points  give my take on what is going on. Then actual options for how to deal with it, opposed to the original advice of :

"Put up with it, blame them, then fire them" .......


Though firstly, I think it is valuable to separate behaviour and the person.

One of the over whelming messages is the original post, is that you judge people and describe them from their behaviours. I suggest that you don't and you define and isolate the behaviour that you find challenging, and see it as your experience of that behaviour instead.

Keep the faith that most people are positive and want the same things, just some have trouble expressing it or communicating frustration.

Once you have identified the behaviour and stopped trying to judge and  blame the person, you can do the first best thing, and that is asses yourself.

There are volumes written yearly akin to : "What pisses us off, tells us about ourselves" etc. I could quote all kinds of philosophy, but you get the idea.

Is the behaviour you are experiencing out of place or inappropriate, or is it your reaction and perception that is magnifying it ?

As with just about anything in life, self awareness is key and also as elusive as it is time consuming to develop, though obviously well worth it.

If possible, consult with someone who's there that you trust. Possibly a colleague or team member. Remember it's by way of understanding are things how you see them, opposed to an opportunity to complain or try and build sides.


Just about all issues (of this kind) I've come across come from poor communication (and expectation), be it typical or deliberate.

Project groups are collections of people attempting to get a common goal achieved. Though within that you have collections of individuals who all see the challenges at hand in a different manner (which is a real strength by the way).

As well as being people, and all that goes with that themselves.

The usual kind of approach for management that reports all these difficulties is mandating and dictating to a group, how to solve the issue as they see it.

There are two fundamental issues here. First, the team will solves the challenges, that's what project teams do, when allowed, and support by facilitation. So focus on the issue, not trying to tell people who likely know better than you how to do it.

This is where trust and respect come in, not the iron first of weak managements "I'm in a suit and have a big title, I have to tell you what to do, what else am I hear for" (that topic I'll leave to Dr Paul Thomas).

One of the most important things to do is communicate, and the most important part of communicating is listening, not talking.

If you are experiencing what you perceive to be negative behaviour by people who are "negative" or "questioning you all the time" .......... find out why!

Resistance is typically a good thing when it's about a project, as someone who can see something you can't is likely trying to tell you something.


If you are from the Dickensian school of management (lets call it "the 80's" and you have a huge Motorola mobile phone you like to shout into in the middle of the office), then control is going to be second nature. Anything Zen is going to involve "Asian people in silk pyjamas waving their hands about".

(As it is I rather like Tai-Chi, it's taught me lots about  dealing with energy, negative or positive, and how to go with the flow and re-direct a lot of the time. Also the costs of going head to head, Yang vs Yang, feeding anger etc.)

There are times when legitimate control and power make sense, for instance a parent physically stopping a child walking into a busy road. Another typical one is the military, because of chain of command (though even there there are caveats for disobeying certain orders).

Now unfortunately I've seen groups that are run at one extreme or the other, a crèche or a military dictatorship.

I'd suggest will intelligent professionals, both are pointless and counter productive.

Though what is apparent to me, is when you have a clash of expectations, within the team. A lot of managers attempt to actually run and direct individuals within a team, i.e. that age old term : micro-managing. The vast majority of IT/software people are going to be resistant to this as they know how to do the job and need support and facilitation, not a condescending head master.

So from the managers point of view, they are resisting and being difficult.

A common and unfortunate mistake, also when done in the context of "I'm more senior, I must be right" there can only be one assumption.

The key here, once again, is the self awareness of what is going on, and what is more important :

Being "right" and in control .... or helping the team to get the job done.

I do make distinction from control and direction, though well functioning teams given a challenge when allowed to will typically self organise and become directive.


Given I'm talking about work, it is a professional environment, there is money changing hands for effort & time, it's not social or family, or personal relationship.

Therefore there is a defined environment, be that an expectation of work or hours spent in a location. Now all good management (or rather team facilitation) is flexible, but to a point.

Allowing someone to be absent for weeks (or even days) and not taking action but to wait and stew until their return and explode is about as far from a constructive or well functioning choice as you can get.

The key here is professional environment. I am not condoning Prima donna behaviour or "the end justifies the means" excuses, though I am advocating that there is mutual respect and acceptance of responsibility, on both sides.

If some one doesn't turn up for work for days in a row, sure you check in on them find out what is going on (it could be an emergency). But you don't simmer in the office "tolerating" their behaviour because they are a technical genius and then explode when they return, you deal with it. It's contractual if nothing else.


There are two sides to the personal aspect that strike me.

First, is that most of these issues come from ego, of any team member. It  could be "da management" or members of the project team. Personally I don't differentiate or accept that any team issues, are only "the workers fault", there is a shocking amount of managers with challenging behaviours, just as there are workers.

So there can be ego on both sides. Management by responsibility of position are there to be aware of, and mediate this, opposed to taking it personally and attempting to "control" the staff.

Specific behaviours of anger, passive aggressive, negative etc, don't particularly bother me as they are just the symptoms of something else. It's just that individuals behaviour to a given situation. There are whole sites about how to deal with individual behaviours, google will help with that.

Find out what is behind the behaviour, and if it is relevant to the project, or if it's personal to them ........... which brings me on to....

Point two: being that we all have our own personal issues, and the vast majority of the time, for the vast majority of people (in my experience) separate that from work. And to a degree that's good, it's professional.

By way of example, the original poster advocates blaming an employee for experiencing an addiction and firing them. Luckily as someone pointed out, in many places that is illegal. Let alone immoral to me.

Some times we are overwhelmed by the situations in our lives, be that burnout a personal crisis, life in general, etc.

How a company supports it's people is very telling of how it's people are going to support the company I've found. My experiences are more of Europe than North America, though I've seen provisions for HR and employee support on both sides of the water.

I don't personally want to run a company and turn it into a counselling help session all day long, though I do accept there are responsibilities and healthy ways of supporting people. Respect at work is a two way street.

Shouting at people or threatening them for not working weekends consistently, and then firing them the first day of holiday they take is no way to do business.

So my advice is to lay off the condescending approaches of :
  • how do we control them
  • how to deal with people who don't do what you say
  • Nerds are X, and this is how you manipulate them
  • etc
And try and look at the bigger picture, and most importantly yourself before trying to blame, control, understand others.